从非指针结构元素进行链表指针赋值的Go代码。

huangapple go评论76阅读模式
英文:

Go linked list pointer assignment from non-pointer struct element

问题

你好!以下是你提供的代码的翻译:

我在Go语言中遇到了一个“无法分配给指针”的错误,很困惑。

这是可以工作的代码:http://play.golang.org/p/P9FjK8A-32,与Go的原始container/list代码相同。

type List struct {
    root Element
    len  int
}

type Element struct {
    next, prev *Element
    list       *List
    Value      interface{}
}

原始代码将root定义为值,并在需要指针类型时引用它,但为什么不一开始就将root定义为指针呢?

type List struct {
    root *Element
    len  int
}

type Element struct {
    next, prev *Element
    list       *List
    Value      interface{}
}

这样会导致错误:http://play.golang.org/p/1gCAR_rcx1 -> invalid memory address or nil pointer dereference

为什么会出现这个错误?
为什么Go在定义nextprev时使用指针,而在定义root时不使用指针?

谢谢!

英文:

https://github.com/golang/go/blob/master/src/container/list/list.go#L49

I am having hard time why I am getting cannot assign to pointer error in Go.

Here's the code that works: http://play.golang.org/p/P9FjK8A-32 which is same as Go's original container/list code

type List struct {
    root Element
    len  int
}

type Element struct {
    next, prev *Element
    list       *List
    Value      interface{}
}

The original code has root as a value and reference it everytime it needs to be in pointer type but why not at first place define root as a pointer?

type List struct {
    root *Element
    len  int
}

type Element struct {
    next, prev *Element
    list       *List
    Value      interface{}
}

This give me an error: http://play.golang.org/p/1gCAR_rcx1 -> invalid memory address or nil pointer dereference

Why am I getting this error?
Why does Go define root as a non-pointer value when it defines next, and prev as pointers?

Thanks

答案1

得分: 1

指针默认为nil,需要进行初始化。

原始代码:

// Init initializes or clears list l.
func (l *List) Init() *List {
  l.root.next = l.root
  l.root.prev = l.root
  l.len = 0
  return l
}

应改为:

// Init initializes or clears list l.
func (l *List) Init() *List {
  l.root = new(Element) // 为了避免解引用空指针,需要进行初始化
  l.root.next = l.root
  l.root.prev = l.root
  l.len = 0
  return l
}

示例代码可在 http://play.golang.org/p/EYSscTMYnn 查看。

在标准库的情况下,root不需要是指针,但对于prevnext来说是必需的,否则结构体定义将会是递归的,这是不允许的,因为理论上会导致无限大小的结构体...

英文:

A pointer is nil by default and needs to be initialized.

This:

// Init initializes or clears list l.
func (l *List) Init() *List {
  l.root.next = l.root
  l.root.prev = l.root
  l.len = 0
  return l
}

should become this:

// Init initializes or clears list l.
func (l *List) Init() *List {
  l.root = new(Element) // necessary to avoid dereferencing a nil pointer
  l.root.next = l.root
  l.root.prev = l.root
  l.len = 0
  return l
}

Demo at http://play.golang.org/p/EYSscTMYnn

In the case of the standard library, it is not necessary to have root be a pointer, however, for prev and next it is necessary, otherwise the struct definition would be recursive, which is not allowed, because it would in theory cause a struct of infinite size...

huangapple
  • 本文由 发表于 2015年3月10日 23:48:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/28968119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定