繁体   English   中英

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

[英]change struct's pointer value in struct's method

我正在尝试将指针缠绕在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方法根本没有引用节点指针指向其他结构

就像其他参数一样,接收方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)
}

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

要使用指针在该位置获取或设置值,您需要使用“间接”运算符。 例如, *node将在该node指向的位置获得LinkedList ,而*node = newHead将在该node指向的位置设置LinkedList

您也可以将指针指向新的内存位置,但是该更改将仅在当前作用域中可见。 在你的情况,这意味着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

游乐场链接

只需将值引用参数点更改为

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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