猿问

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

我正在尝试为字段赋值,但我的程序因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)

}


呼啦一阵风
浏览 242回答 1
1回答

慕后森

关键是var b bytes.Buffer不给你一个nil指针,它给你一个bytes.Buffer对象,它的所有字段都用零值初始化(用机器术语来说,零字节)。规范说零值是“布尔值为假,整数为 0,浮点数为 0.0,字符串为“”,指针、函数、接口、切片、通道和映射为 nil”;点击该链接了解更多详情。可以制作自己的零值结构体,并且Go 团队鼓励这样做。struct Position { x, y int }是一个简单的例子,而 Effective Go 给出了一个更现实的例子。但请注意,这不会使nil 指针起作用;您仍然需要new(Node)或var n Node分配零Node。对于bytes.Buffer.零值的另一个常见用途:无论您的用户在何处直接创建您的类型的结构(就像人们所做的那样http.Server),零值是他们未指定的任何字段的默认值。这是许多其他地方的默认设置:如果您从关闭的频道接收到未找到的地图密钥,您可能会得到什么,可能还有其他地方。
随时随地看视频慕课网APP

相关分类

Go
我要回答