如何获得结构的字符串表示形式?

对于我的应用程序,字符串是否可读并不重要。

168286 次浏览

将结构编码为字符串的一种流行方法是使用 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)

如果大小很重要,可以使用 %v,但是我喜欢 %#v,因为它还包括字段名和 struct 类型的名称。

第三个变体是 %+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,

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

问问 Bjørn Hansen

BenchmarkStructSprint: fmt.Sprintf("%v", &a)

BenchmarkStructSprintPlus: fmt.Sprintf("%+v", &a)

结果表明,json.Marshal具有更好的性能。