英文:
change struct's pointer value in struct's method
问题
我正在努力理解Go语言中的指针。我有这段代码:
package main
import (
"fmt"
)
// LinkedList 类型
type LinkedList struct {
data int
next *LinkedList
}
// InsertList 将一个项插入链表
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方法根本没有将节点指针引用到不同的结构体上。
英文:
I am trying to wrap my head around pointer in go. I have this code right here
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)
}
and The output is
node = &{data:0 next:<nil>}
I would like to understand that why is node = &newHead my InsertList method did not reference the node pointer to a different struct at all
答案1
得分: 5
接收器 node 被按值传递,就像其他参数一样,所以在函数中所做的任何更改都不会被调用者看到。如果你希望函数修改函数外部存在的某个东西,函数需要处理指向该对象的指针。在你的情况下,node 是一个指针,但你真正想要的是指向表示链表本身的指针。例如:
package main
import (
"fmt"
)
type LinkedListNode struct {
data int
next *LinkedListNode
}
type LinkedList struct {
head *LinkedListNode
}
// InsertList 将一个项插入链表
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)
}
希望这可以帮助到你!
英文:
The receiver node is passed by value just like other parameters, so any changes you make in the function are not seen by the caller. If you want a function to modify something that exists outside the function, the function needs to be dealing with a pointer to that object. In your case, node is a pointer, but what you really want is a pointer to something that represents the list itself. For example:
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)
}
答案2
得分: 3
只需将值引用参数指向的位置更改为
func (node *LinkedList) InsertList(data int) {
newHead := LinkedList{data, node}
*node = newHead // 在这里取消引用
}
英文:
Just change the value reference argument point to
func (node *LinkedList) InsertList(data int) {
newHead := LinkedList{data, node}
*node = newHead //<- dereference here
}
答案3
得分: 2
想象一下:每个变量都必须存储在内存的某个位置上,你可以使用指针来存储该位置,而不仅仅是变量本身。
要使用指针获取或设置该位置上的值,你需要使用"间接"运算符。例如,*node将获取node指向的位置上的LinkedList,*node = newHead将设置node指向的位置上的LinkedList。
你还可以将指针指向新的内存位置,但该更改只在当前作用域中可见。在你的情况下,这意味着node = &newHead只会影响InsertList中的node指针,而不会影响main中的node指针。
这里有一个使用普通函数的简单示例,尽管方法也适用相同的规则:
// 修改`x`指向的值
func modifyValue(x *int) {
fmt.Printf(" modifyValue: x=%3d @ %p\n", *x, x)
*x = 1
fmt.Printf(" modifyValue: x=%3d @ %p\n", *x, x)
}
// 修改指针`x`本身
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
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论