为了账号安全,请及时绑定邮箱和手机立即绑定

我应该什么时候初始化 Golang 变量

我应该什么时候初始化 Golang 变量

Go
SMILET 2022-03-03 15:07:58
Golang 中有一些变量:全局变量:var a int局部变量:func hello() { var a int }返回变量:func hello() (a int) {}Golang 有时会自动初始化一些变量,但我不知道何时以及为什么?这让我很困惑。例子:type User struct {  Name string `json:"name"`  Age  int    `json:"age"`}func foo(bts []byte) {  var a User  err := json.Unmarshal(bts, &a)  // It's ok}func bar(bts []byte) (a *User) {  err := json.Unmarshal(bts, a) // It will crash}使用前我应该初始化哪一个?
查看完整描述

2 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

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 指向的值中。


查看完整回答
反对 回复 2022-03-03
?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

Go 是一种非常一致的语言:总是自动初始化变量:

通过引用表达式中的变量来检索变量的值;它是分配给变量的最新值。如果一个变量还没有被赋值,它的值是它的类型的零值。

零值为:

0对于数字类型,

false对于布尔类型,和

""(空字符串)用于字符串。

对于映射、切片、指针和接口,零值是nil.

对于自定义类型,以某种方式使零值有用是惯用的(即通常被认为是最佳实践),通常作为默认值或重要的标记。


编辑:您的示例不会崩溃。也许您从中删除的其中一件事是导致崩溃?


查看完整回答
反对 回复 2022-03-03
  • 2 回答
  • 0 关注
  • 218 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信