如何将 []int8 转换为字符串 [英] How to convert []int8 to string

查看:32
本文介绍了如何将 []int8 转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[]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 因为 byteuint8 (并且 []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.

byteuint8 的别名,范围为 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屋!

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