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


77

对于我的应用程序,字符串是否为人类可读的都没有关系。


1
您是否要序列化结构?您应该为此真正使用gob。
rmmh

Answers:


96

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


正是我需要的!+1给您
abw333

我注意到您的第二个问题以及您的目的是什么。JSON可能有用,但如果要使用输出字符串创建哈希来测试相等性,则不是。正如Ask所提到的,您将遇到地图问题。这也适合使用fmt.Sprintf
2013年

不知道键必须大写才能显示在JSON中。
jiyinyiyong

104

如果它是“单向”序列化(用于调试或日志记录等),则fmt.Printf("%#v", var)非常好。(更新:将输出放入字符串而不是打印出来,请使用str := fmt.Sprintf("%#v", var)

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

第三种变体%+v将包括字段名称,但不包括结构类型。

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

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


1
感谢您的答复。我可能应该在我的问题中指定要获取程序而不是控制台中的值。特别是,我想将字符串转换为字节数组。当我执行“ [] byte(fmt.Printf(“%v”,var))”时,程序会抱怨“单值上下文中的多值fmt.Printf()”。我假设这是因为Printf不返回字符串值,而仅将其打印到控制台。您知道解决此问题的方法吗?
2013年

我想出了如何使用ANisus的响应来执行此操作,但是对您+1表示满意。
2013年

如果在程序中需要它,请使用fmt.Sprintf而不是Printf。如果您使用JSON,请注意,映射值可能不会在每次运行时都以相同的顺序返回(尽管fmt printf也可能是这种情况,但我没有检查)。
问比约恩·汉森

7

您还可以在该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)

此代码的工作副本在此处play.golang.org/p/SCDnaMFQLJc
汤姆L

4

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

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!

2

使用jsonfmt.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)@AskBjørnHansen

BenchmarkStructSprint:`fmt.Sprintf(“%v”,&a)

BenchmarkStructSprintPlus:`fmt.Sprintf(“%+ v”,&a)

结果是json.Marshal更好的性能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.