将非字符串值写入io.Writer的Write方法中

huangapple go评论97阅读模式
英文:

Writing non-string value into io.Writer Write method

问题

我正在尝试将非字符串值(如整数、浮点数、切片甚至map[string]interface{})写入io.Writer。我期望写入的结果按照预期的类型返回。如果我将整数写入Write,那么在解码返回的[]byte后,我将得到整数类型的值。在Go语言中如何实现这个功能?

英文:

I'm trying to write non-string value into io.Writer like integer, float, slices, or even map[string]interface{}. I'm expecting the result written returned as expected type written. If I wrote int into the Write, then I will get integer type value after decoding the []byte returned. How to do it in Go?

答案1

得分: 2

你可能正在寻找的是encoding/gob,因为该编码保留了Go类型信息。它默认支持一些内置的Go类型和一些基本的gob类型。如果你想要编码/解码gob默认不支持的类型,你可以使用gob.Register函数注册这些类型。

编码示例:

var v interface{} = uint8(123)
if err := gob.NewEncoder(w).Encode(&v); err != nil {
    panic(err)
}

注意,上述代码将*interface{}类型的值传递给Encode函数,如果在另一端解码器事先不知道类型,并且必须使用*interface{}类型作为Decode函数的参数,这是必要的。如果解码器知道传入数据的具体类型,则可以将具体类型的值传递给Encode函数。


解码示例:

var v interface{}
if err := gob.NewDecoder(r).Decode(&v); err != nil {
    panic(err)
}

fmt.Println(v)      // 输出: 123
fmt.Printf("%T", v) // 输出: uint8

https://play.golang.org/p/cCtQse8BoqZ

英文:

What you're probably looking for is encoding/gob since that encoding retains the Go type information. Out of the box it supports some of the builtin Go types and some of the basic gob types. If you want to encode/decode types not supported out of the box by gob you can use the gob.Register function to register those types.

To encode:

var v interface{} = uint8(123)
if err := gob.NewEncoder(w).Encode(&v); err != nil {
	panic(err)
}

Note that the above passes a value of type *interface{} to Encode, this is necessary if, at the other end, the decoder doesn't know the type beforehand and has to also use type *interface{} as the argument to Decode. If you have a scenario where the decoder knows the concrete type the of the incoming data then you can also pass a value of that concrete type to Encode.


To decode:

var v interface{}
if err := gob.NewDecoder(r).Decode(&v); err != nil {
    panic(err)
}

fmt.Println(v)      // output: 123
fmt.Printf("%T", v) // output: uint8

https://play.golang.org/p/cCtQse8BoqZ

答案2

得分: 0

这似乎可以实现:

package main
import "encoding/json"

func main() {
   a := []interface{}{
      31, 3.1, []int{12,31}, map[string]interface{}{"month": 12, "day": 31},
   }
   b, err := json.Marshal(a)
   if err != nil {
      panic(err)
   }
   println(string(b)) // [31,3.1,[12,31],{"day":31,"month":12}]
}

https://pkg.go.dev/encoding/json#Marshal

英文:

This seems to do it:

package main
import "encoding/json"

func main() {
   a := []interface{}{
      31, 3.1, []int{12,31}, map[string]interface{}{"month": 12, "day": 31},
   }
   b, err := json.Marshal(a)
   if err != nil {
      panic(err)
   }
   println(string(b)) // [31,3.1,[12,31],{"day":31,"month":12}]
}

https://pkg.go.dev/encoding/json#Marshal

huangapple
  • 本文由 发表于 2021年7月15日 22:20:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/68395601.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定