将Go结构转换为JSON


181

我正在尝试使用该json包将Go结构转换为JSON,但我得到的只是{}。我敢肯定这是完全显而易见的,但我看不到。

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func main() {
    user := &User{name:"Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Printf("Error: %s", err)
        return;
    }
    fmt.Println(string(b))
}

然后,当我尝试运行它时,我得到以下信息:

$ 6g test.go && 6l -o test test.6 && ./test 
{}

Answers:


328

您需要导出User.name字段,以便在json包装可以看到它。将name字段重命名为Name

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    Name string
}

func main() {
    user := &User{Name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}

输出:

{"Name":"Frank"}

87
请注意,您可以添加`json:"name"`到struct字段定义的末尾以保留输出名称。
达斯汀

12
我懂了。我有点喜欢这种语言,但是我认为某些语法元素已经深入人心。如果结构成员的名称确定了行为,那么这是错误的。
magiconair

1
好吧,用名称来确定行为是好是坏可以争论不休:),但这肯定可以很容易地知道是否导出了字段,而不必检查其他地方。
Olof

6
@magiconair:第一个符文的大小写确定可见性,这比“结构成员的名称决定行为”要合理得多。可见性元数据需要存储在某处,并且需要语法来表达它。最终确定,采用第一个字符的大写字母时,权衡最少的方法效果最好。在Go1发布之前,其他方案曾被尝试并被拒绝。
deft_code 2014年

11
从那以后我走了很长一段路,现在非常喜欢这种语言,包括大写形式的导出。
magiconair 2014年

62

相关问题:

我在将结构转换为JSON,从Golang作为响应发送结构时遇到了麻烦,然后,后来通过Ajax在JavaScript中捕获了相同的结构。

浪费了很多时间,所以在这里发布解决方案。

在Go中:

// web server

type Foo struct {
    Number int    `json:"number"`
    Title  string `json:"title"`
}

foo_marshalled, err := json.Marshal(Foo{Number: 1, Title: "test"})
fmt.Fprint(w, string(foo_marshalled)) // write response to ResponseWriter (w)

在JavaScript中:

// web call & receive in "data", thru Ajax/ other

var Foo = JSON.parse(data);
console.log("number: " + Foo.number);
console.log("title: " + Foo.title);

希望这对某人有帮助。
祝你好运。


6

结构值编码为JSON对象。每个导出的struct字段都将成为对象的成员,除非:

  • 该字段的标签为“-”,或
  • 该字段为空,并且其标签指定“ omitempty”选项。

空值为false,0,任何nil指针或接口值以及任何长度为零的数组,切片,映射或字符串。对象的默认键字符串是struct字段名称,但可以在struct字段的标记值中指定。struct字段的标记值中的“ json”键是键名,后跟可选的逗号和选项。


2

您可以定义自己的自定义MarshalJSON和UnmarshalJSON方法,并有意控制应包括的内容,例如:

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func (u *User) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
        Name     string `json:"name"`
    }{
        Name:     "customized" + u.name,
    })
}

func main() {
    user := &User{name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}
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.