如何将 []int8 转换为字符串 [英] How to convert []int8 to string
问题描述
从 []int8
转换为字符串的最佳方式(最快的性能)是什么?
What's the best way (fastest performance) to convert from []int8
to string?
对于 []byte
我们可以做 string(byteslice)
,但对于 []int8
它会报错:
For []byte
we could do string(byteslice)
, but for []int8
it gives an error:
cannot convert ba (type []int8) to type string
我从 的 SliceScan()
方法获得了 ba
*sqlx.Rows
生成 []int8
而不是 string
I got the ba
from SliceScan()
method of *sqlx.Rows
that produces []int8
instead of string
这个解决方案是最快的吗?
Is this solution the fastest?
func B2S(bs []int8) string {
ba := []byte{}
for _, b := range bs {
ba = append(ba, byte(b))
}
return string(ba)
}
EDIT 我的错,它是 uint8
而不是 int8
.. 所以我可以做 string(ba)
直接.
EDIT my bad, it's uint8
instead of int8
.. so I can do string(ba)
directly.
推荐答案
提前说明: 提问者首先声明输入切片是 []int8
所以这就是答案是为了.后来他意识到输入是 []uint8
可以直接转换为 string
因为 byte
是 uint8
(并且 []byte
=> 语言规范).
Note beforehand: The asker first stated that input slice is []int8
so that is what the answer is for. Later he realized the input is []uint8
which can be directly converted to string
because byte
is an alias for uint8
(and []byte
=> string
conversion is supported by the language spec).
你不能转换不同类型的切片,你必须手动完成.
You can't convert slices of different types, you have to do it manually.
问题是我们应该转换成什么类型的切片?我们有 2 个候选者:[]byte
和 []rune
.字符串在内部存储为 UTF-8 编码的字节序列([]byte
),string
也可以转换为符文片段.该语言支持将这两种类型([]byte
和 []rune
)转换为 string
.
Question is what type of slice should we convert to? We have 2 candidates: []byte
and []rune
. Strings are stored as UTF-8 encoded byte sequences internally ([]byte
), and a string
can also be converted to a slice of runes. The language supports converting both of these types ([]byte
and []rune
) to string
.
rune
是一个 unicode 代码点.如果我们尝试以一对一的方式将 int8
转换为 rune
,如果输入包含已编码的字符,它将失败(意味着输出错误)到多个字节(使用 UTF-8),因为在这种情况下,多个 int8
值应该以一个 rune
结尾.
A rune
is a unicode codepoint. And if we try to convert an int8
to a rune
in a one-to-one fashion, it will fail (meaning wrong output) if the input contains characters which are encoded to multiple bytes (using UTF-8) because in this case multiple int8
values should end up in one rune
.
让我们从字符串 "世界"
开始,它的字节是:
Let's start from the string "世界"
whose bytes are:
fmt.Println([]byte("世界"))
// Output: [228 184 150 231 149 140]
还有它的符文:
fmt.Println([]rune("世界"))
// [19990 30028]
只有 2 个符文和 6 个字节.所以显然 1 对 1 int8
->rune
映射行不通,我们必须使用 1-1 int8
-><代码>字节映射.
It's only 2 runes and 6 bytes. So obviously 1-to-1 int8
->rune
mapping won't work, we have to go with 1-1 int8
->byte
mapping.
byte
是 uint8
的别名,范围为 0..255
,将其转换为 []int8
(范围为 -128..127
)如果字节值 > 127,我们必须使用 -256+bytevalue
所以 "世界"
[]int8
中的 string
看起来像这样:
byte
is alias for uint8
having range 0..255
, to convert it to []int8
(having range -128..127
) we have to use -256+bytevalue
if the byte value is > 127 so the "世界"
string
in []int8
looks like this:
[-28 -72 -106 -25 -107 -116]
我们想要的反向转换是:bytevalue = 256 + int8value
如果 int8
是负数但我们不能像 int8 那样做
(范围 -128..127) 而不是 byte
(范围 0..255) 所以我们还必须先将其转换为 int
(然后再返回)以 byte
结尾).这可能看起来像这样:
The backward conversion what we want is: bytevalue = 256 + int8value
if the int8
is negative but we can't do this as int8
(range -128..127) and neither as byte
(range 0..255) so we also have to convert it to int
first (and back to byte
at the end). This could look something like this:
if v < 0 {
b[i] = byte(256 + int(v))
} else {
b[i] = byte(v)
}
但实际上,由于有符号整数是使用 2 的补码来表示的,我们得到如果我们简单地使用 byte(v)
转换(在负数的情况下相当于 256 + v
),结果相同.
But actually since signed integers are represented using 2's complement, we get the same result if we simply use a byte(v)
conversion (which in case of negative numbers this is equivalent to 256 + v
).
注意:由于我们知道切片的长度,分配具有此长度的切片并使用索引 []
设置其元素会快得多,而不是调用内置的 append
函数.
Note: Since we know the length of the slice, it is much faster to allocate a slice with this length and just set its elements using indexing []
and not calling the built-in append
function.
所以这是最终的转换:
func B2S(bs []int8) string {
b := make([]byte, len(bs))
for i, v := range bs {
b[i] = byte(v)
}
return string(b)
}
在 Go Playground 上尝试一下.
这篇关于如何将 []int8 转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!