英文:
String pointers
问题
考虑以下程序(http://play.golang.org/p/IbAstvudtE):
package main
import (
"fmt"
)
func changeStringValueNotOK(dest *string, src string) {
dest = &src
}
func changeStringValueOK(dest *string, src string) {
*dest = src
}
func main() {
a := "Hello"
b := "World"
changeStringValueNotOK(&a, b)
fmt.Println(a) // 仍然是"Hello"
changeStringValueOK(&a, b)
fmt.Println(a) // 现在是"World"
}
我的目标是调用一个函数并改变字符串的值。第二个函数可以正常工作,但第一个函数不行。
问题:*dest = src
和 dest = &src
的含义是什么?我猜前者是“dest的内容现在是src”,而后者是“更改dest变量,使其指向src的地址”,丢弃了先前的值,但即使我是对的,我也不明白*dest = src
是如何工作的。
希望我的问题不太模糊。
英文:
Consider the following program (http://play.golang.org/p/IbAstvudtE):
package main
import (
"fmt"
)
func changeStringValueNotOK(dest *string, src string) {
dest = &src
}
func changeStringValueOK(dest *string, src string) {
*dest = src
}
func main() {
a := "Hello"
b := "World"
changeStringValueNotOK(&a, b)
fmt.Println(a) // still "Hello"
changeStringValueOK(&a, b)
fmt.Println(a) // now "World"
}
My goal is to call a function and change the value of string. Works fine with the second function, but not with the first.
Question: what is the meaning of *dest = src
compared to dest = &src
? I guess the former is "the contents of dest is now src" and the latter is "change the dest variable so that it now points to the address of src" which discards the previous value, but not the contents of a. But even if I am right, I don't understand how the *dest = src
works.
I hope my question isn't too fuzzy.
答案1
得分: 5
*dest = src
意思是:将dest
指向的值设置为src
中的值。所以它是有效的。
dest = &src
意思是:将dest
的值设置为src
的地址。由于dest
是changeStringValueNotOK
的形式参数,所以这个改变(只改变指针,而不是指向的值)只在本地可见。由于改变后的值实际上没有被使用,它的总体效果是没有操作。
英文:
*dest = src
is: Set the value pointed at by dest
to the value in src
. So it's effective.
dest = &src
is: Set the value of dest
to the address of src
. As dest is a formal parameter of changeStringValueNotOK
the change (to the pointer only, not to the pointee) is visible only locally. As the changed value is not really used, it's total effect is a no operation.
答案2
得分: 4
只是为了以图形方式帮助可视化,在你的主函数中有这样的代码:
数据 变量
| ... |
-------
| Hello |<----- <a string>
-------
| World |<----- <b string>
-------
| ... |
当你向这些函数提供参数时,变成了这样:
数据 参数
| ... |
-------
| Hello |<----- <a string> <----- <dest *string>
-------
| World |<----------------------- <src string>
-------
| ... |
在这种情况下,当你执行 *dest = src
时,你会得到:
数据 参数
| ... |
-------
| Hello | ,- <a string> <---- <dest *string>
------- |
| World |<--/
| |<---------------------- <src string>
-------
| ... |
请注意,这实际上改变了 a
本身,所以当你返回到之前的作用域时,你会观察到这个变化。
另一方面,如果你执行 dest = &src
,你会得到:
数据 参数
| ... |
-------
| Hello | <dest *string> ----,
------- |
| World |<---------------------- <src string> <---/
-------
| ... |
这并不能解决你的问题,因为 dest 和 src 都是局部于它们所在的函数。
顺便说一下,这种参数传递方式是一种常见的 C 习惯用法,但在 Go 中,你通常会通过返回新值来改变这样的字符串。
英文:
Just to help visualize it graphically, in your main function you have this:
Data Variables
| ... |
-------
| Hello |<----- <a string>
-------
| World |<----- <b string>
-------
| ... |
When you provide the parameters to either of these functions, it becomes:
Data Parameters
| ... |
-------
| Hello |<----- <a string> <----- <dest *string>
-------
| World |<----------------------- <src string>
-------
| ... |
With that scenario, when you do *dest = src
, you get:
Data Parameters
| ... |
-------
| Hello | ,- <a string> <---- <dest *string>
------- |
| World |<--/
| |<---------------------- <src string>
-------
| ... |
Note that this effectively changes a
itself, so when you return to the prior scope, you'll observe the change.
On the other hand, if you do dest = &src
, you'd instead get:
Data Parameters
| ... |
-------
| Hello | <dest *string> ----,
------- |
| World |<---------------------- <src string> <---/
-------
| ... |
Which doesn't solve your problem, because both dest and src are local to the functions they're in.
As a side note, this kind of parameter passing is a common C idiom, but in Go you'd generally change such a string by returning the new value instead.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论