drgc9632 2017-11-17 14:04
浏览 45
已采纳

不变的字符串和指针地址

In Go spec is written:

Strings are immutable: once created, it is impossible to change the contents of a string.

I have following code:

str := "hello"
fmt.Printf("%p
",&str) // 0x1040c128
fmt.Printf("%v
",str) // hello
ptr := &str
*ptr = "world"
fmt.Printf("%p
",&str) // 0x1040c128
fmt.Printf("%v
",str) // world  

I would have expected &str address was changed after *ptr = "world". As it would happen with Java, where we reassign String references.

What is 'immutability' here?

  • 写回答

1条回答 默认 最新

  • douniang3866 2017-11-17 14:11
    关注

    string values are immutable.

    str is not a string value. It's a variable (of string type). And values of variables may be changed, that's what you'd expect from any programming language.

    "hello" is a string value, and this is what is immutable. "world" is another string value, and when you assign "world" to str, you just assign another, different value to the str variable. It doesn't matter if you're doing it directly to str, or via a pointer. You're just changing the value of the variable denoted by str.

    Immutable means you cannot take the string value "world", and change its second character for example. If you have a function for example which receives a string argument, whatever it receives (e.g. "hello"), you can be sure it will always remain the same. No matter when / how you print this string value, it will always be "hello".

    A string value is a struct value under the hood, represented by the reflect.StringHeader type:

    type StringHeader struct {
        Data uintptr
        Len  int
    }
    

    It basically stores a data pointer (to the byte array holding the UTF-8 encoded value of the text), and the byte-length of the string value. The data array and its length are not exposed to you, so you can't modify them. This is one element of making sure that string values are immutable. Another element is that although string values can be indexed (which indexes its bytes), you can not assign new values to the index expressions. E.g. it is valid to use the value "abc"[0], but it is invalid to assign a new value to it like "abc"[0] = 'x'. Similarly, you cannot take the address of an index expression indexing a string value (else you could modify the pointed value and thus indirectly the string value).

    This is what the language spec guarantees. Note that there are certain ways to still change string values, e.g. using package unsafe, but this falls outside the guarantees of the spec:

    Package unsafe contains operations that step around the type safety of Go programs.

    Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.

    The "moment" you import package unsafe, you'll lose any guarantees and safety provided by the language spec, and from there on you can't complain for anything. But without using these "special" means, it cannot happen that a string value gets altered.

    Read the blog post Strings, bytes, runes and characters in Go for how string is implemented and works in Go.

    See related questions:

    What is the difference between the string and []byte in Go?

    What are the possible consequences of using unsafe conversion from []byte to string in go?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题