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

问题描述 投票:0回答:5

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

string struct go
5个回答
163
投票

如果它是“单向”序列化(用于调试或日志记录或其他),那么

fmt.Printf("%#v", var)
非常好。 (更新:要将输出放入字符串而不是打印它,请使用
str := fmt.Sprintf("%#v", var)

如果大小很重要,您可以使用

%v
,但我喜欢
%#v
,因为它还将包含字段名称和结构类型的名称。

第三个变体是

%+v
,它将包含字段名称,但不包含结构类型。

它们都记录在 fmt 文档的顶部。

如果您需要双向序列化 JSON,Gob 或 XML 是 Go 中最简单/内置的选项,请参阅 编码包


138
投票

将结构编码为字符串的一种流行方法是使用 JSON

您有一定的限制,例如无法获取所有信息(例如每个字段的具体类型)、仅序列化导出的字段、不处理递归值。但这是序列化数据的简单标准方法。

工作示例:

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


20
投票

String()
函数附加到命名结构允许我们将结构转换为字符串。

package main

import "fmt"

type Foo struct {
    Bar string
}

func (f Foo) String() string {
    return fmt.Sprintf("Foo says: %q", f.Bar)
}

func main() {
    fmt.Println(Foo{Bar: "Hello World!"})
}

输出:

Foo says: "Hello World!"

10
投票

您还可以使用该结构接收器添加一个函数。

// 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)
}

因此打印这个结构体字段将返回一个字符串。

fmt.Println(urls.URLS)

3
投票

使用

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
正在使用
json.Marshal
@Matheus Santana

BenchmarkStructSprintSharp
fmt.Sprintf("%#v", &a)
@问Bjørn Hansen

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

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

结果是,

json.Marshal
表现更好。

© www.soinside.com 2019 - 2024. All rights reserved.