如何分配字符串字节数组

我想把字符串赋值给bytes数组:

var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
arr[k] = byte(v)
}

还有别的方法吗?

543268 次浏览

例如,

package main


import "fmt"


func main() {
s := "abc"
var a [20]byte
copy(a[:], s)
fmt.Println("s:", []byte(s), "a:", a)
}

输出:

s: [97 98 99] a: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

我认为这样更好。

package main


import "fmt"


func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}

检查这里:http://play.golang.org/p/vpnAWHZZk7

安全简单:

[]byte("Here is a string....")

除了上面提到的方法,你还可以做一个小技巧

s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))

开始播放:http://play.golang.org/p/xASsiSpQmC

你不应该使用这个:-)

小菜一碟:

arr := []byte("That's all folks!!")

最终创建了特定于数组的方法来实现这一点。很像编码/二进制包,每个int类型都有特定的方法。例如binary.BigEndian.PutUint16([]byte, uint16)

func byte16PutString(s string) [16]byte {
var a [16]byte
if len(s) > 16 {
copy(a[:], s)
} else {
copy(a[16-len(s):], s)
}
return a
}


var b [16]byte
b = byte16PutString("abc")
fmt.Printf("%v\n", b)

输出:

[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]

请注意,我希望填充在左边,而不是右边。

http://play.golang.org/p/7tNumnJaiN

用于从字符串转换为字节片,string -> []byte:

[]byte(str)

用于将数组转换为片,[20]byte -> []byte:

arr[:]

用于将字符串复制到数组,string -> [20]byte:

copy(arr[:], str)

与上面相同,但首先显式地将字符串转换为slice:

copy(arr[:], []byte(str))

  • 内置的copy函数只复制一个片,一个片。
  • 数组是“底层数据”,而切片是“底层数据的一个视口”。
  • 使用[:]使数组符合片的条件。
  • 字符串不符合可以复制的片的条件,但它符合可以复制的片的条件(字符串是不可变的)。
  • 如果字符串太长,copy将只复制匹配的部分字符串(多字节符文可能只复制部分,这将破坏结果字符串的最后一个符文)。

这段代码:

var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)

...给出如下输出:

array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)

我也使它在去操场可用

数组是值…切片更像指针。也就是说,[n]type[]type是不兼容的,因为它们本质上是两个不同的东西。你可以通过使用arr[:]来获得一个指向数组的片,它返回一个有arr作为后台存储的片。

将例如[]byte的切片转换为[20]byte的一种方法是实际分配一个[20]byte,你可以使用var [20]byte(因为它是一个值…没有make需要),然后复制数据到它:

buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)

本质上,很多其他答案的错误在于[]type不是一个数组。

[n]T[]T是完全不同的东西!

在使用reflect时,[]T不是数组类型,而是Slice类型,而[n]T是数组类型。

你也不能使用map[[]byte]T,但你可以使用map[[n]byte]T

这有时可能很麻烦,因为许多函数在[]byte上操作,而一些函数返回[n]byte(最显著的是crypto/*中的哈希函数)。 例如,sha256哈希值是[32]byte而不是[]byte,因此当初学者尝试将其写入文件时,例如:

sum := sha256.Sum256(data)
w.Write(sum)

他们会得到一个错误。正确的方法是使用

w.Write(sum[:])

但是,你到底想要什么?只是按字节访问字符串?你可以使用以下方法轻松地将string转换为[]byte:

bytes := []byte(str)

但这不是数组,而是切片。另外,byte != rune。如果你想操作“字符”,你需要使用rune…不是byte

将字符串转换为字节片

您需要一种快速的方法将[]字符串转换为[]字节类型。用于将文本数据存储到随机访问文件或要求输入数据为[]字节类型的其他类型的数据操作等情况。

package main


func main() {


var s string


//...


b := []byte(s)


//...
}

这在使用ioutil时很有用。WriteFile,它接受字节片作为它的数据参数:

WriteFile func(filename string, data []byte, perm os.FileMode) error

另一个例子

package main


import (
"fmt"
"strings"
)


func main() {


stringSlice := []string{"hello", "world"}


stringByte := strings.Join(stringSlice, " ")


// Byte array value
fmt.Println([]byte(stringByte))


// Corresponding string value
fmt.Println(string([]byte(stringByte)))
}

输出:

你好,世界

请检查链接操场上

如果有人正在寻找之间的快速考虑使用unsafe转换,您可以参考下面的比较。

package demo_test


import (
"testing"
"unsafe"
)


var testStr = "hello world"
var testBytes = []byte("hello world")


// Avoid copying the data.
func UnsafeStrToBytes(s string) []byte {
return *(*[]byte)(unsafe.Pointer(&s))
}


// Avoid copying the data.
func UnsafeBytesToStr(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}


func Benchmark_UnsafeStrToBytes(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = UnsafeStrToBytes(testStr)
}
}


func Benchmark_SafeStrToBytes(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = []byte(testStr)
}
}


func Benchmark_UnSafeBytesToStr(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = UnsafeBytesToStr(testBytes)
}
}


func Benchmark_SafeBytesToStr(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = string(testBytes)
}
}

go test -v -bench="^Benchmark"国营=没有

输出

cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
Benchmark_UnsafeStrToBytes
Benchmark_UnsafeStrToBytes-8    1000000000               0.2465 ns/op
Benchmark_SafeStrToBytes
Benchmark_SafeStrToBytes-8      289119562                4.181 ns/op
Benchmark_UnSafeBytesToStr
Benchmark_UnSafeBytesToStr-8    1000000000               0.2530 ns/op
Benchmark_SafeBytesToStr
Benchmark_SafeBytesToStr-8      342842938                3.623 ns/op
PASS