0

I am implementing a linked list in Go. I wrote a method to insert a node at the beginning of the linked list:

func (n *node) insertAtBegining(d int){
    nn := &node{d,n}
    n = nn
}

The method being a pointer receiver should update the node n, but it fails to do so.

For example,

head.printList()
head.insertAtBegining(30)
head.printList()

returns

42 -> 56 -> 89 -> nil
42 -> 56 -> 89 -> nil

You can see the full implementation at https://play.golang.org/p/rpI6lbAywOQ.

What am I doing wrong?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Shreyansh Deb
  • 53
  • 1
  • 1
  • 6
  • See possible duplicate: [Can the pointer in a struct pointer method be reassigned to another instance?](https://stackoverflow.com/questions/35421495/can-the-pointer-in-a-struct-pointer-method-be-reassigned-to-another-instance/35426997?r=SearchResults#35426997) – icza Feb 01 '20 at 09:33
  • https://play.golang.org/p/Xw3wCGRBNEl – mkopriva Feb 01 '20 at 14:32

1 Answers1

0

The root of the issue is that calling head.insertAtBegining(30) does not change the value of head (it still points at the node{42, nil}).

You have developed this on the asumption that the n = nn in insertAtBegining will update head but that is not the case. I think it's easier to understand if insertAtBegining is a standard function rather than a method:

insertAtBegining(head, 30)
...
func insertAtBegining(n *node, d int) *node{
    nn := &node{d,n}
    n = nn
}

As Go passes all parameters by value (you can pass a pointer but that is passed as a value) I think it's clear that this would not change head (if you wanted to do that you would need to define the function func insertAtBegining(n **node, d int) *node{ and pass it &head.

The issue is the same in your method.

The simplest fix for this is to redefine insertAtBegining as (playground):

func (n *node) insertAtBegining(d int) *node{
    nn := &node{d,n}
    return nn
}

It now returns the new head so you use it like: head = head.insertAtBegining(30).

Another approach is to encapuslate the list management within a struct; this is the approach taken in list.List. Doing this has the advantage that the user needs no understanding of how the list is stored.

Brits
  • 14,829
  • 2
  • 18
  • 31