英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论