2 回答
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 指向的值中。
TA贡献2065条经验 获得超13个赞
Go 是一种非常一致的语言:它总是自动初始化变量:
通过引用表达式中的变量来检索变量的值;它是分配给变量的最新值。如果一个变量还没有被赋值,它的值是它的类型的零值。
0
对于数字类型,
false
对于布尔类型,和
""
(空字符串)用于字符串。
对于映射、切片、指针和接口,零值是nil
.
对于自定义类型,以某种方式使零值有用是惯用的(即通常被认为是最佳实践),通常作为默认值或重要的标记。
编辑:您的示例不会崩溃。也许您从中删除的其中一件事是导致崩溃?
- 2 回答
- 0 关注
- 218 浏览
添加回答
举报