字符串指针

huangapple go评论156阅读模式
英文:

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 = srcdest = &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的地址。由于destchangeStringValueNotOK的形式参数,所以这个改变(只改变指针,而不是指向的值)只在本地可见。由于改变后的值实际上没有被使用,它的总体效果是没有操作。

英文:
*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 |&lt;----- &lt;a string&gt;
 -------
| World |&lt;----- &lt;b string&gt;
 -------
|  ...  |

When you provide the parameters to either of these functions, it becomes:

  Data                            Parameters

|  ...  |
 -------
| Hello |&lt;----- &lt;a string&gt; &lt;----- &lt;dest *string&gt;
 -------
| World |&lt;----------------------- &lt;src string&gt;
 -------
|  ...  |

With that scenario, when you do *dest = src, you get:

  Data                           Parameters

|  ...  |
 -------
| Hello |    ,- &lt;a string&gt; &lt;---- &lt;dest *string&gt;
 -------    |
| World |&lt;--/      
|       |&lt;---------------------- &lt;src string&gt;
 -------
|  ...  |

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 = &amp;src, you'd instead get:

  Data                           Parameters

|  ...  |
 -------
| Hello |                        &lt;dest *string&gt; ----,
 -------                                            |
| World |&lt;---------------------- &lt;src string&gt;  &lt;---/
 -------
|  ...  |

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.

huangapple
  • 本文由 发表于 2013年8月29日 01:12:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/18494183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定