为什么在Golang中不允许对字符串进行字符切换?

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

Why character switching in string is not allowed in Golang?

问题

我理解Go语言中的字符串实际上是一个字节的数组。为什么不允许使用str[0] = str[1]的赋值操作呢?谢谢!

  1. str := "hello"
  2. str[0] = str[1]
  3. // 期望的结果是 eello
  4. <details>
  5. <summary>英文:</summary>
  6. I understand that Go string is basically an array of byte. What is the explanation why str[0] = str[1] is not allowed? Thanks!

str := "hello"
str[0] = str[1]

// expecting eello

答案1

得分: 3

我理解到Go语言中的字符串基本上是一个字节数组。

不完全正确。一个字符串由以下组成:

  • 指向一个字节数组的指针,
  • 一个对应于该数组长度的整数。

如果你可以更新给定字符串变量中的单个符文(rune),那么字符串将是可变的,这与Go语言设计者的意愿相悖(参考:https://golang.org/ref/spec#String_types):

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

请参阅golang.org博客上的这篇文章(https://go.dev/blog/strings):

在Go语言中,字符串实际上是一个只读的字节切片。

不可变性有很多优点,比如易于推理,但它也可能被视为一种麻烦。当然,覆盖一个字符串变量是合法的:

  1. str := "hello"
  2. str = "eello"

此外,你始终可以将字符串转换为可变的数据结构(即[]byte[]rune),进行所需的更改,然后再将结果转换回字符串。

  1. str := "hello"
  2. fmt.Println(str)
  3. bs := []byte(str)
  4. bs[0] = bs[1]
  5. str = string(bs)
  6. fmt.Println(str)

输出:

  1. hello
  2. eello

Playground

然而,要注意这样做涉及到复制操作,如果字符串很长和/或重复进行此操作,可能会影响性能。

英文:

> I understand that Go string is basically an array of bytes.

Not exactly. A string is made up of

  • a pointer to an array of bytes, and
  • an integer that corresponds to the length of that array.

If you could update individual runes of a given string variable, then strings would be mutable, against the wishes of the Go designers:

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

See also this post on the golang.org blog:

> In Go, a string is in effect a read-only slice of bytes.

Immutability has many advantages—for one thing, it's easy to reason about—but it can be perceived as a nuisance. Of course, overwriting a string variable is legal:

  1. str := &quot;hello&quot;
  2. str = &quot;eello&quot;

Moreover, you can always convert the string to a data structure that is mutable (i.e. a []byte or a []rune), make the required changes, and then convert the result back to a string.

  1. str := &quot;hello&quot;
  2. fmt.Println(str)
  3. bs := []byte(str)
  4. bs[0] = bs[1]
  5. str = string(bs)
  6. fmt.Println(str)

Output:

  1. hello
  2. eello

(Playground)

However, be aware that doing so involves copying, which can hurt performance if the string is long and/or if it's done repeatedly.

答案2

得分: 0

Go字符串是不可变的,并且表现得像只读的字节切片。要更新数据,请使用rune切片代替。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. str := "hello"
  7. fmt.Println(str)
  8. buf := []rune(str)
  9. buf[0] = buf[1]
  10. s := string(buf)
  11. fmt.Println(s)
  12. }

输出:

  1. hello
  2. eello
英文:

Go strings are immutable and behave like read-only byte slices,To update the data, use a rune slice instead;

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. func main() {
  6. str := &quot;hello&quot;
  7. fmt.Println(str)
  8. buf := []rune(str)
  9. buf[0] = buf[1]
  10. s := string(buf)
  11. fmt.Println(s)
  12. }

Output:

  1. hello
  2. eello

huangapple
  • 本文由 发表于 2021年9月9日 13:22:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/69112633.html
匿名

发表评论

匿名网友

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

确定