英文:
Why the pointer is losing its value in this Go program
问题
我不明白为什么指针s
在input()
方法初始化后仍然是nil
。有什么想法吗?
package main
import "fmt"
type ps string
func(s *ps)input(){
x := ps("a")
s = &x
}
func(s *ps)output(){
}
func main() {
var v *ps
v.input()
if v == nil{
fmt.Println("v shouldn't be nil")
}
}
在这段代码中,input()
方法接收一个指向ps
类型的指针s
。在方法内部,它创建了一个新的ps
类型变量x
,并将s
指向x
的地址。然而,这里的问题是,s
是一个指针的副本,而不是原始指针本身。因此,对s
的修改不会影响到原始指针v
。
要解决这个问题,你可以将input()
方法修改为接收一个指向指针的指针,这样就可以修改原始指针的值。修改后的代码如下:
package main
import "fmt"
type ps string
func(s **ps)input(){
x := ps("a")
*s = &x
}
func(s *ps)output(){
}
func main() {
var v *ps
v.input()
if v == nil{
fmt.Println("v shouldn't be nil")
}
}
现在,input()
方法接收一个指向指针的指针s
,并将s
指向x
的地址。这样,对s
的修改将会影响到原始指针v
,并且v
将不再是nil
。
英文:
I don't understand why the pointer s
is nil
even after the input()
method initialised it. Any idea?
package main
import "fmt"
type ps string
func(s *ps)input(){
x := ps("a")
s = &x
}
func(s *ps)output(){
}
func main() {
var v *ps
v.input()
if v == nil{
fmt.Println("v shouldn't be nil")
}
}
Playground http://play.golang.org/p/jU2hoMP7TS
答案1
得分: 1
你需要两件事——main
需要为input
可以写入的ps
分配空间,你可以通过将var v *ps
替换为v := new(ps)
来实现。字符串将是""
,但它的内容并不重要,只要在内存中为input
可以写入的string header分配了空间即可。正如Momer所说,否则指针将为nil
,你的程序在尝试解引用时会发生恐慌。
为了通过指针赋值,input
需要使用*s = x
。由于*s
在非正式场合下表示“获取s
指向的内容”,你可以将其理解为“将s
指向的内容更改为x
”。通常,在点运算符和方法调用周围的自动引用/解引用行为会为你节省这个步骤,但是当你通过指针类型进行赋值或进行其他操作(如算术运算、索引等)时,代码中需要有解引用操作。
英文:
You need two things--main
needs to allocate space for a ps
that input
can write into, which you can do by replacing var v *ps
with v := new(ps)
. The string will be ""
, but it doesn't matter what it is, just that there's space set aside in memory for a string header that input
can write to. As Momer said, otherwise the pointer's nil
and your program panics trying to dereference it.
And in order to assign through a pointer, input
needs to use *s = x
. Since *s
is, informally, "get what s
points to", you can read that as "change what s
points to to x
". Usually the automatic ref/deref behavior around the dot operator and method calls saves you from that, but when you assign through a pointer type or do other operations (arithmetic, indexing, etc.) the dereference needs to be there in the code.
答案2
得分: 0
v值(0)被传递到v.input中。传递的值被存储在一个局部变量s中。s的值被修改。没有人将新的s值保存回v中。
如果你想在函数中修改某个值,你必须传递该值的指针(或者对于切片、映射等类型,传递引用)。
如果你想改变指针的值,你应该传递指向你的指针的指针。
Alex
英文:
v value (0) is passed into v.input. Passed value is stored in a local variable s. s value is modified. No one is saving new s value back into v.
If you want something modified in your function, you must pass pointer to the value. (or reference for slices, maps and so on).
If you want to change pointer value, you should pass pointer to your pointer.
Alex
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论