不变的字符串和指针地址 [英] Immutable string and pointer address

查看:63
本文介绍了不变的字符串和指针地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Go 规范中写道:

字符串是不可变的:一旦创建,就无法更改 字符串的内容.

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

我有以下代码:

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

我希望在*ptr = "world"之后更改&str地址.就像Java那样,我们在其中重新分配String引用.

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

什么是不变性"?

推荐答案

string 是不可变的.

str不是string值.这是变量(属于string类型).并且变量的值可能会更改,这是您对任何编程语言所期望的.

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"是一个string值,这是不可变的. "world"是另一个string值,将"world"分配给str时,只需将另一个不同的值分配给str变量.可以直接对str进行操作,也可以通过指针进行操作.您只是在更改由str表示的变量的值.

"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.

不可变的表示您不能采用string"world",例如,更改其第二个字符.例如,如果您有一个函数接收一个string自变量,无论它接收到什么(例如"hello"),都可以确保它始终保持不变.无论何时/如何打印此string值,它始终为"hello".

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".

string值是一个底层结构值,由 reflect.StringHeader 类型:

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

type StringHeader struct {
    Data uintptr
    Len  int
}

它基本上存储一个数据指针(指向保存文本的UTF-8编码值的字节数组)和string值的字节长度.数据数组及其长度不向您公开,因此您无法对其进行修改.这是确保string值不可变的元素之一.另一个元素是,尽管可以为string值建立索引(索引其字节),但是您不能将新值分配给索引表达式.例如.使用值"abc"[0]是有效的,但是像"abc"[0] = 'x'这样为其分配新值是无效的.同样,您不能获取索引string值的索引表达式的地址(否则可以修改指向的值,从而间接地修改string值).

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).

这是语言规范的保证.请注意,有些方法仍然可以更改string值,例如使用软件包 unsafe ,但这超出了规范的保证范围:

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:

不安全打包包含围绕Go程序的类型安全性进行的操作.

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

导入不安全的软件包可能是不可携带的,并且不受Go 1兼容性准则的保护.

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

时刻"导入软件包unsafe,您将失去语言规范所提供的任何保证和安全,并且从那时起您就不会有任何抱怨.但是,在没有使用这些特殊"功能的情况下,没有意味着string值不会被更改.

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.

阅读博客文章 Go中的字符串,字节,符文和字符,了解如何实现string并可以在Go中使用.

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

查看相关问题:

什么是字符串和Go中[] byte之间的区别?

在go中使用从[]字节到字符串的不安全转换有什么可能的后果?

这篇关于不变的字符串和指针地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆