对于我的应用程序,字符串是否可读并不重要。
将结构编码为字符串的一种流行方法是使用 JSON。
您有一些限制,例如不能获取所有信息(比如每个字段的特定类型) ,只能序列化导出的字段,以及不能处理递归值。但它是序列化数据的一种简单的标准方法。
Working example:
package main import ( "fmt" "encoding/json" ) type s struct { Int int String string ByteSlice []byte } func main() { a := &s{42, "Hello World!", []byte{0,1,2,3,4}} out, err := json.Marshal(a) if err != nil { panic (err) } fmt.Println(string(out)) }
输出如下:
{"Int":42,"String":"Hello World!","ByteSlice":"AAECAwQ="}
https://play.golang.org/p/sx-xdSxAOG
如果它是一个“单向”序列化(用于调试或日志记录等) ,那么 fmt.Printf("%#v", var)非常好。(更新: 要将输出放入字符串而不是打印它,使用 str := fmt.Sprintf("%#v", var)。
fmt.Printf("%#v", var)
str := fmt.Sprintf("%#v", var)
如果大小很重要,可以使用 %v,但是我喜欢 %#v,因为它还包括字段名和 struct 类型的名称。
%v
%#v
第三个变体是 %+v,它将包含字段名,但不包含结构类型。
%+v
它们都被记录在 Fmt 文档的顶部。
如果需要双向序列化 JSON,Gob 或 XML 是 Go 中最简单/内置的选项,请参见 编码包。
您还可以使用这个 struct 接收器添加一个函数。
// URL : Sitemap Xml type URL struct { Loc string `xml:"loc"` } // URLSET : Sitemap XML type URLSET struct { URLS []URL `xml:"url"` } // converting the struct to String format. func (u URL) String() string { return fmt.Sprintf(u.Loc) }
因此,打印这个 struct 字段将返回一个字符串。
fmt.Println(urls.URLS)
将 String ()函数附加到命名的 struct 允许我们将 struct 转换为字符串。
package main import "fmt" type foo struct { bar string } func (f foo) String() string { return fmt.Sprintf("Foo Says: %s", f.bar) } func main() { fmt.Println(foo{"Hello World!"}) }
output: Foo Says: Hello World!
Using json or fmt.Sprintf, I make a benchmark,
json
fmt.Sprintf
BenchmarkStructJson-8 1000000 1773 ns/op BenchmarkStructSprintSharp-8 200000 6139 ns/op BenchmarkStructSprint-8 500000 2763 ns/op BenchmarkStructSprintPlus-8 300000 4373 ns/op
BenchmarkStructJson is using json.Marshal @Matheus Santana
BenchmarkStructJson
json.Marshal
问问 Bjørn Hansen
BenchmarkStructSprint: fmt.Sprintf("%v", &a)
BenchmarkStructSprint
fmt.Sprintf("%v", &a)
BenchmarkStructSprintPlus: fmt.Sprintf("%+v", &a)
BenchmarkStructSprintPlus
fmt.Sprintf("%+v", &a)
结果表明,json.Marshal具有更好的性能。