如何在golang中分配nil结构的字段

时间:2015-03-22 06:34:53

标签: go

我尝试为某个字段分配值,但我的程序会因runtime error: invalid memory address or nil pointer dereference而感到恐慌。

package main

type Node struct {
    Value int
}

func (n *Node) SetValue(value int) {
    n.Value = value
}

func main() {
    var n *Node

    n.SetValue(1)
}

这是合理的,因为变量是零 但我允许一些Go内部结构被允许这样做,例如bytes.Buffer

package main

import "bytes"
import "io"
import "os"

func main() {
    var b bytes.Buffer
    b.Write([]byte("Hello world"))
    io.Copy(os.Stdout, &b)
}

这是`bytes.Buffer源代码

func (b *Buffer) Write(p []byte) (n int, err error) {
    b.lastRead = opInvalid
    m := b.grow(len(p))
    return copy(b.buf[m:], p), nil
}

只有内置结构可以做到的事情,或者我的代码可以实现这一点吗?

修改
这是工作示例。谢谢@twotwotwo的建议。

package main

import "fmt"

type Node struct {
    Value int
}

func (n *Node) SetValue(value int) {
    n.Value = value
}

func main() {
    var n Node

    n.SetValue(1)

    fmt.Println(n.Value)
}

1 个答案:

答案 0 :(得分:6)

关键是var b bytes.Buffer没有为您提供nil指针,它会为您提供一个bytes.Buffer对象,其所有字段的初始值均为零值(以机器术语表示) ,零字节)。 The spec says零值是"假的是布尔值,0是整数,0.0是浮点数,""对于字符串,nil用于指针,函数,接口,切片,通道和映射&#34 ;;请点击该链接了解更多详情。

可以创建自己的零值和the Go team encourages it的结构。 struct Position { x, y int }是一个简单的例子,Effective Go提供了一个更现实的例子。但请注意,这并不能使 nil指针工作;您仍然需要new(Node)var n Node来分配零Nodebytes.Buffer也是如此。

零值的另一个常见用途:无论用户何时直接创建您的类型的结构(例如,http.Server),零值是他们不指定的任何字段的默认值。它是许多其他地方的默认设置:如果您从封闭频道收到,可能会获得未找到地图密钥的内容,以及其他可能的地址密钥。