json - json.Unmarshal() 如何工作以及它如何存储在变量中?

标签 json pointers go unmarshalling

刚开始使用 Go,我对我正在学习的教程有一点疑问。我读到 Unmarshall 是某种 JSON 编码,我的疑问是:err = json.Unmarshal(body, &p) 为什么我们要将编码后的主体分配给 err 以及当我看不到分配给 p 的任何内容时 p.Stuff.Fruit 是如何获取值的。

注意:produce 是不同的包,其中包含一些类型和数组。*

func main() {
  url := "http://localhost:12337"
  res, err := http.Get(url)
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  body, err := ioutil.ReadAll(res.Body)
  if err != nil {
    panic(err)
  }

  var p produce.Payload

  err = json.Unmarshal(body, &p)  // I cant get this
  if err != nil {
    panic(err)
  }

  // how are these getting the values assigned to them

  fmt.Println(p.Stuff.Fruit)
  fmt.Println(p.Stuff.Veggies)
}

最佳答案

my doubt here is: err = json.Unmarshal(body, &p) why are we assigning the encoded body to err

你不知道。您将 body 传递给 json.Unmarshal()函数,并将其返回值分配给err变量,它会告诉您解码是否失败(或者如果errnil则成功) )。

how is p.Stuff.Fruit getting the value when I can't see anything assigned to p

你将 p 的地址传递给 json.Unmarshal(),所以它有一个指向你的变量的指针,所以如果它修改了 pointed 值(由指针指向),它会修改您拥有的相同值 (p)。

看这个简单的例子:

func change(p *int) {
    *p = 3
}

func main() {
    var i int
    fmt.Println("Before", i)
    change(&i)
    fmt.Println("After", i)
}

输出(在 Go Playground 上尝试):

Before 0
After 3

main() 函数中,我们没有给局部变量 i 赋值,但是我们将它的地址传递给 change() 函数,它修改了 pointed 值,所以如果我们在 change() 调用之后打印 i 的值,我们会看到它值(value)改变了。

您将 p 的地址传递给 json.Unmarshal(),因此它将能够修改存储在 p 中的值。在引擎盖下,json包使用反射(包 reflect )来发现 p 的运行时类型,并根据您传递给它的 JSON 文档对其进行修改以进行解析。

关于json - json.Unmarshal() 如何工作以及它如何存储在变量中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48985627/

相关文章:

go - Windows命令行在Golang中的参数中附加引号

php - MySQL 多行的 JSON 编码

ruby-on-rails-3 - 如何将对象从 rake 任务传递给 rabl View

带有静态指针的 C++ 类

postgresql - Heroku Postgres 无法从 heroku 应用程序连接

go - 我收到的以下 go 代码有什么问题 'all goroutines are asleep - deadlock!'

jQuery/AJAX - 响应格式

javascript - 通过javascript/D3加载json

ios - 为什么我们在 Swift 中使用 &error?

c - 奇怪的 malloc 崩溃问题