将Go结构体转换为JSON

huangapple go评论107阅读模式
英文:

Converting Go struct to JSON

问题

我正在尝试使用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 
{}

<details>
<summary>英文:</summary>

I am trying to convert a Go struct to JSON using the `json` package but all I get is `{}`. I am certain it is something totally obvious but I don&#39;t see it.


    package main

    import (
        &quot;fmt&quot;
        &quot;encoding/json&quot;
    )

    type User struct {
        name string
    }

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

Then when I try to run it I get this:

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


</details>


# 答案1
**得分**: 518

你需要[导出][1] `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"}


  [1]: http://golang.org/doc/go_spec.html#Exported_identifiers

<details>
<summary>英文:</summary>

You need to [export][1] the `User.name` field so that the `json` package can see it. Rename the `name` field to `Name`.

    package main
    
    import (
    	&quot;fmt&quot;
    	&quot;encoding/json&quot;
    )
    
    type User struct {
    	Name string
    }
    
    func main() {
    	user := &amp;User{Name: &quot;Frank&quot;}
    	b, err := json.Marshal(user)
    	if err != nil {
    		fmt.Println(err)
    		return
    	}
    	fmt.Println(string(b))
    }

Output:

    {&quot;Name&quot;:&quot;Frank&quot;}


  [1]: http://golang.org/doc/go_spec.html#Exported_identifiers

</details>



# 答案2
**得分**: 93

相关问题:

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

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

在Go中:

    // web服务器
    
    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)) // 将响应写入ResponseWriter (w)
    
    
    
在JavaScript中:

    // 通过Ajax/其他方式调用并在"data"中接收

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

<details>
<summary>英文:</summary>

Related issue:

I was having trouble converting struct to JSON, sending it as response from Golang, then, later catch the same in JavaScript via Ajax.

Wasted a lot of time, so posting solution here.

 
In Go:  

    // web server
    
    type Foo struct {
        Number int    `json:&quot;number&quot;`
    	Title  string `json:&quot;title&quot;`
    }

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

    // web call &amp; receive in &quot;data&quot;, thru Ajax/ other

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



</details>



# 答案3
**得分**: 13

这是一个有趣的问题,使用新的go版本非常容易。你应该这样做:
```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))
}

将这个名字改为Name。

英文:

This is an interesting question, it is very easy using the new go versions. You should do this:

package main

import (
    &quot;fmt&quot;
    &quot;encoding/json&quot;
)

type User struct {
    Name string `json:&quot;name&quot;`
}

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

Change this name to Name.

答案4

得分: 8

你可以定义自己的自定义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))
}
英文:

You can define your own custom MarshalJSON and UnmarshalJSON methods and intentionally control what should be included, ex:

package main

import (
    &quot;fmt&quot;
    &quot;encoding/json&quot;
)

type User struct {
    name string
}

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

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


</details>



# 答案5
**得分**: 7

结构体值被编码为JSON对象。除非满足以下条件,否则每个导出的结构体字段都成为对象的成员:

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

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

<details>
<summary>英文:</summary>

Struct values encode as JSON objects. Each exported struct field becomes
a member of the object unless:

- the field&#39;s tag is &quot;-&quot;, or
- the field is empty and its tag specifies the &quot;omitempty&quot; option.

The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero. The object&#39;s default key string is the struct field name but can be specified in the struct field&#39;s tag value. The &quot;json&quot; key in the struct field&#39;s tag value is the key name, followed by an optional comma and options.

</details>



huangapple
  • 本文由 发表于 2011年11月25日 22:54:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/8270816.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定