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

查看:85
本文介绍了如何将[] 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

我从 *sqlx.Rows SliceScan()方法中获得了ba,它生成了[]int8而不是string

I got the ba from SliceScan() method of *sqlx.Rows that produces []int8 instead of string

此解决方案最快吗?

func B2S(bs []int8) string {
    ba := []byte{}
    for _, b := range bs {
        ba = append(ba, byte(b))
    }
    return string(ba)
}

编辑,我不好,它是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 => string转换受

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.

A 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个字节.因此很明显,一对一int8-> rune映射将不起作用,我们必须使用1-1 int8-> byte映射.

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是具有范围0..255uint8的别名,要将其转换为[]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)
}

去游乐场上尝试.

这篇关于如何将[] int8转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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