Think of it like this: every variable must be stored at some location in memory, and you can use a pointer to store that location rather than just the variable itself.
To get or set the value at that location using the pointer, you need to use the "indirection" operator. For example, *node will get the LinkedList at the location that node points to, and *node = newHead will set the LinkedList at the location that node points to.
You can also point the pointer to a new memory location, but that change will only be visible in the current scope. In your case, that means node = &newHead only affects the node pointer in InsertList, not the node pointer in main.
Here's a simpler example using normal functions, though the same rules apply for methods:
// Changes the value `x` points to
func modifyValue(x *int) {
fmt.Printf(" modifyValue: x=%3d @ %p\n", *x, x)
*x = 1
fmt.Printf(" modifyValue: x=%3d @ %p\n", *x, x)
}
// Changes the pointer `x` itself
func modifyPointer(x *int) {
fmt.Printf("modifyPointer: x=%3d @ %p\n", *x, x)
n := 1
x = &n
fmt.Printf("modifyPointer: x=%3d @ %p\n", *x, x)
}
func main() {
x := 200
fmt.Printf(" main: x=%3d @ %p\n\n", x, &x)
modifyPointer(&x)
fmt.Printf(" main: x=%3d @ %p\n\n", x, &x)
modifyValue(&x)
fmt.Printf(" main: x=%3d @ %p\n\n", x, &x)
}
Output:
main: x=200 @ 0x1040e0f8
modifyPointer: x=200 @ 0x1040e0f8
modifyPointer: x= 1 @ 0x1040e134
main: x=200 @ 0x1040e0f8
modifyValue: x=200 @ 0x1040e0f8
modifyValue: x= 1 @ 0x1040e0f8
main: x= 1 @ 0x1040e0f8
Playground link