将Go结构转换为JSON

mag*_*air 153 json go

我试图使用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))
}
Run Code Online (Sandbox Code Playgroud)

然后,当我尝试运行它时,我得到了这个:

$ 6g test.go && 6l -o test test.6 && ./test 
{}
Run Code Online (Sandbox Code Playgroud)

pet*_*rSO 294

您需要导出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))
}
Run Code Online (Sandbox Code Playgroud)

输出:

{"Name":"Frank"}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以在结构字段定义的末尾添加`\`json:"name"\``以保留输出名称. (79认同)
  • 我已经走了很长一段路,现在非常喜欢包括大写出口在内的语言. (11认同)
  • 我知道了.我有点像语言,但我认为一些语法元素走得很远.如果结构成员的名称确定了行为,那么这是错误的. (10认同)
  • @magiconair:_第一个符文的大写确定visibility_,是比一个更合理的想法,_"结构成员的名称决定行为"_.可见性元数据需要存储在某个地方,并需要语法来表达它.最终,确定选择第一个字母的大写最好,最少的权衡取舍.在Go1发布之前,其他方案被尝试并被拒绝. (6认同)
  • 好吧,名称决定行为的好坏是可以争论的 :) 但它确实可以很容易地知道一个字段是否被导出,而无需检查其他地方。 (2认同)

Man*_*ddy 55

相关问题:

我无法将struct转换为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)
Run Code Online (Sandbox Code Playgroud)

在JavaScript中:

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

var Foo = JSON.parse(data);
console.log("number: " + Foo.number);
console.log("title: " + Foo.title);
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人.
祝你好运.


小智 14

这是一个有趣的问题,使用新的 go 版本非常容易。你应该做这个:

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    Name string `json:"name"`
}

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

将此名称更改为名称。


Hie*_* Vo 10

您可以定义自己的自定义 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))
}

Run Code Online (Sandbox Code Playgroud)


GoL*_*ter 6

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

  • 字段的标记是" - ",或
  • 该字段为空,其标签指定"omitempty"选项.

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