简体   繁体   中英

Go linked list pointer assignment from non-pointer struct element

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

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM