在struct的方法中更改struct的指针值

时间:2017-02-05 02:15:49

标签: go

我正试着把头围绕着指针。我这里有这个代码

package main

import (
    "fmt"
)

// LinkedList type
type LinkedList struct {
    data int
    next *LinkedList
}

// InsertList will insert a item into the list
func (node *LinkedList) InsertList(data int) {
    newHead := LinkedList{data, node}
    node = &newHead
}

func main() {
    node := &LinkedList{}
    node.InsertList(4)
    fmt.Printf("node = %+v\n", node)
}

,输出

node = &{data:0 next:<nil>}

我想了解为什么node = &newHead我的InsertList方法根本没有引用指向不同结构的节点指针

3 个答案:

答案 0 :(得分:3)

接收方node与其他参数一样按值传递,因此调用方看不到您在函数中所做的任何更改。如果希望函数修改函数外部存在的某些函数,则该函数需要处理指向该对象的指针。在你的情况下,node是一个指针,但你真正想要的是指向代表列表本身的东西的指针。例如:

package main

import (
    "fmt"
)

type LinkedListNode struct {
    data int
    next *LinkedListNode
}

type LinkedList struct {
    head *LinkedListNode
}

// InsertList will insert a item into the list
func (list *LinkedList) InsertList(data int) {
    newHead := &LinkedListNode{data, list.head}
    list.head = newHead
}

func main() {
    var list LinkedList
    list.InsertList(4)
    fmt.Printf("node = %+v\n", list.head)
    list.InsertList(7)
    fmt.Printf("node = %+v\n", list.head)
}

答案 1 :(得分:2)

可以这样想:每个变量都必须存储在内存中的某个位置,并且您可以使用指针来存储该位置而不仅仅是变量本身。

要使用指针获取或设置该位置的值,您需要使用&#34;间接&#34;运营商。例如,*node会在LinkedList指向的位置获得node,而*node = newHead会将LinkedList设置在node的位置指向。

您还可以将指针指向新的内存位置,但该更改仅在当前范围内可见。在您的情况下,这意味着node = &newHead仅影响node中的InsertList指针,而不影响node中的main指针。

这是使用普通函数的一个更简单的例子,尽管相同的规则适用于方法:

// 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)
}

输出:

         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

答案 2 :(得分:1)

只需将值引用参数指向

即可
func (node *LinkedList) InsertList(data int) {
    newHead := LinkedList{data, node}
    *node = newHead   //<- dereference here 
}