string和[]byte在Go语言中有什么区别?

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

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

问题

s := "some string"
b := []byte(s) // 将字符串转换为字节切片
s2 := string(b) // 将字节切片转换为字符串

在Go语言中,string[]byte有什么区别?

何时使用"he"或"she"?

为什么?

bb := []byte{'h','e','l','l','o',127}
ss := string(bb)
fmt.Println(ss)

hello

输出结果只是"hello",缺少了127,有时我觉得这很奇怪。

英文:
s := "some string"
b := []byte(s) // convert string -> []byte
s2 := string(b) // convert []byte -> string

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

When to use "he" or "she"?

Why?

bb := []byte{'h','e','l','l','o',127}
ss := string(bb)
fmt.Println(ss)

> hello

The output is just "hello", and lack of 127, sometimes I feel that it's weird.

答案1

得分: 20

string[]byte是不同的类型,但它们可以相互转换:

  • []byte转换为string类型会生成一个字符串,其中连续的字节是切片的元素。
  • string类型的值转换为[]byte类型会生成一个切片,其中连续的元素是字符串的字节。

在Go语言中,字符串实际上非常简单:它们只是带有一些额外语法支持的只读字节切片。

使用哪个取决于你的需求。字符串是不可变的,因此它们可以共享,并且你可以确保它们不会被修改。

字节切片可以被修改(即可以修改其背后的数组内容)。

如果你需要频繁地将string转换为[]byte(例如,因为你需要将其写入io.Writer()),你应该考虑一开始就将其存储为[]byte

还要注意,你可以有string常量,但没有切片常量。这可能是一个小的优化。此外要注意:

  • 如果s是一个字符串常量,表达式len(s)是常量。

此外,如果你正在使用已经编写好的代码(无论是标准库、第三方包还是你自己的代码),在大多数情况下,都会明确给出你需要传递的参数和值,或者返回的值。例如,如果你从io.Reader中读取数据,你需要一个[]byte来接收读取的字节,而不能使用string

在这个例子中:

bb := []byte{'h','e','l','l','o',127}

这里发生的是你使用了一个复合字面量(切片字面量)来创建和初始化一个新的[]byte类型的切片(使用了短变量声明)。你指定了常量来列出切片的初始元素。你还使用了一个字节值127,这取决于平台/控制台,可能有或可能没有可视化表示。

英文:

string and []byte are different types, but they can be converted to one another:

> 3 . Converting a slice of bytes to a string type yields a string whose successive bytes are the elements of the slice.
>
> 4 . Converting a value of a string type to a slice of bytes type yields a slice whose successive elements are the bytes of the string.

Blog: Arrays, slices (and strings): The mechanics of 'append':

> Strings are actually very simple: they are just read-only slices of bytes with a bit of extra syntactic support from the language.

Also read: Strings, bytes, runes and characters in Go

When to use one over the other?

Depends on what you need. Strings are immutable, so they can be shared and you have guarantee they won't get modified.

Byte slices can be modified (meaning the content of the backing array).

Also if you need to frequently convert a string to a []byte (e.g. because you need to write it into an io.Writer()), you should consider storing it as a []byte in the first place.

Also note that you can have string constants but there are no slice constants. This may be a small optimization. Also note that:

> The expression len(s) is constant if s is a string constant.

Also if you are using code already written (either standard library, 3rd party packages or your own), in most of the cases it is given what parameters and values you have to pass or are returned. E.g. if you read data from an io.Reader, you need to have a []byte which you have to pass to receive the read bytes, you can't use a string for that.


This example:

bb := []byte{'h','e','l','l','o',127}

What happens here is that you used a composite literal (slice literal) to create and initialize a new slice of type []byte (using Short variable declaration). You specified constants to list the initial elements of the slice. You also used a byte value 127 which - depending on the platform / console - may or may not have a visual representation.

答案2

得分: 4

晚了一点,但希望这可以帮到你。

简单来说

  • 位(Bit):机器用01来表示所有的信息。
  • 字节(Byte):由8个位(bit)组成,表示UTF-8编码,即字符。
  • type:给定数据类型的切片。切片是动态大小的数组。
  • byte:这是一个字节切片,即一个动态大小的数组,其中包含字节,即每个元素是一个UTF-8字符。
  • 字符串(String):字节的只读切片,即不可变的。

有了这些基础知识:

s := "Go"
bs := []byte(s)
fmt.Printf("%s", bs)     // 输出:Go
fmt.Printf("%d", bs)     // 输出:[71 111]

或者

bs := []byte{71, 111}
fmt.Printf("%s", bs)     // 输出:Go

%s 将字节切片转换为字符串

%d 获取字节的UTF-8十进制值


重要提示:

由于字符串是不可变的,它们不能在内存中更改。每次你向字符串添加或删除内容时,Go都会在内存中创建一个新的字符串。另一方面,字节切片是可变的,所以当你更新一个字节切片时,你不会在内存中重新创建新的内容。

因此,在选择合适的数据结构时,可能会对你的应用程序性能产生影响。

英文:

Late but i hope this could help.

In simple words

  • Bit: 0 and 1 is how machines represents all the information
  • Byte: 8 bits that represents UTF-8 encodings i.e. characters
  • type: slice of a given data type. Slices are dynamic size arrays.
  • byte: this is a byte slice i.e. a dynamic size array that contains bytes i.e. each element is a UTF-8 character.
  • String: read-only slices of bytes i.e. immutable

With all this in mind:

s := "Go"
bs := []byte(s)
fmt.Printf("%s", bs)     // Output: Go
fmt.Printf("%d", bs)     // Output: [71 111]

or

bs := []byte{71, 111}
fmt.Printf("%s", bs)     // Output: Go

%s converts byte slice to string

%d gets UTF-8 decimal value of bytes


IMPORTANT:

As strings are immutable, they cannot be changed within memory, each time you add or remove something from a string, GO creates a new string in memory. On the other hand, byte slices are mutable so when you update a byte slice you are not recreating new stuffs in memory.

So choosing the right structure could make a difference in your app performance.

huangapple
  • 本文由 发表于 2015年9月17日 16:39:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/32625959.html
匿名

发表评论

匿名网友

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

确定