Golang 将初始化所有变量(不是有时,不是一些):


在您的代码中:


func bar(bts []byte) (a *User) {

  err := json.Unmarshal(bts, a) // It will crash

}

您传递了一个 nil 指针,但您需要一个由 指向的值a,而不是一个 nil 指针:

因此您可以创建一个 Value 然后将这个 Value 的地址存储在里面a:


当您使用var a *Useror时func bar(bts []byte) (a *User):

Thea是指向User类型的指针,它被初始化为零值,即nil,

请参见(The Go Playground):


package main


import "fmt"


func main() {

    var a *User

    fmt.Printf("%#v\n\n", a)    

}


type User struct {

    Name string `json:"Name"`

    Age  int    `json:"Age"`

}

输出:


(*main.User)(nil)

您可以使用a = &User{}它来初始化它,就像这个工作代码(The Go Playground):


package main


import (

    "encoding/json"

    "fmt"

)


func foo(bts []byte) (*User, error) {

    var a User

    err := json.Unmarshal(bts, &a) // It's ok

    return &a, err

}


func bar(bts []byte) (a *User, err error) {

    a = &User{}

    err = json.Unmarshal(bts, a) // It's ok

    return

}

func main() {

    str := `{ "Name": "Alex", "Age": 3 }`

    u, err := foo([]byte(str))

    if err != nil {

        panic(err)

    }

    fmt.Printf("%#v\n\n", u) // &main.User{Name:"Alex", Age:3}


    u, err = bar([]byte(str))

    if err != nil {

        panic(err)

    }

    fmt.Printf("%#v\n\n", u) // &main.User{Name:"Alex", Age:3}


}


type User struct {

    Name string `json:"Name"`

    Age  int    `json:"Age"`

}

输出:


&main.User{Name:"Alex", Age:3}


&main.User{Name:"Alex", Age:3}

变量声明:


变量声明创建一个或多个变量,将相应的标识符绑定到它们,并给每个变量一个类型和一个初始值。


初始值(零值):


当通过声明或调用为变量分配存储空间new时new,或者通过复合文字或调用创建值时make,并且未提供显式初始化,则为变量或值赋予默认值. 此类变量或值的每个元素都针对其类型设置为零值: false对于布尔值、0整数、0.0浮点数、""字符串 以及nil指针、函数、接口、切片、通道和映射。这种初始化是递归完成的,例如,如果没有指定值,结构数组的每个元素都将其字段归零。


并查看func Unmarshal(data []byte, v interface{}) error文档:


Unmarshal 解析 JSON 编码的数据并将结果存储在 v 指向的值中。