我想把字符串赋值给bytes数组:
var arr [20]byte str := "abc" for k, v := range []byte(str) { arr[k] = byte(v) }
还有别的方法吗?
例如,
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)。
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:
string -> []byte
[]byte(str)
用于将数组转换为片,[20]byte -> []byte:
[20]byte -> []byte
arr[:]
用于将字符串复制到数组,string -> [20]byte:
string -> [20]byte
copy(arr[:], str)
与上面相同,但首先显式地将字符串转换为slice:
copy(arr[:], []byte(str))
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作为后台存储的片。
[n]type
[]type
arr
将例如[]byte的切片转换为[20]byte的一种方法是实际分配一个[20]byte,你可以使用var [20]byte(因为它是一个值…没有make需要),然后复制数据到它:
[]byte
[20]byte
var [20]byte
make
buf := make([]byte, 10) var arr [10]byte copy(arr[:], buf)
本质上,很多其他答案的错误在于[]type不是一个数组。
[n]T和[]T是完全不同的东西!
[n]T
[]T
在使用reflect时,[]T不是数组类型,而是Slice类型,而[n]T是数组类型。
你也不能使用map[[]byte]T,但你可以使用map[[n]byte]T。
map[[]byte]T
map[[n]byte]T
[n]byte
crypto/*
[32]byte
sum := sha256.Sum256(data) w.Write(sum)
他们会得到一个错误。正确的方法是使用
w.Write(sum[:])
但是,你到底想要什么?只是按字节访问字符串?你可以使用以下方法轻松地将string转换为[]byte:
string
bytes := []byte(str)
但这不是数组,而是切片。另外,byte != rune。如果你想操作“字符”,你需要使用rune…不是byte。
byte
rune
您需要一种快速的方法将[]字符串转换为[]字节类型。用于将文本数据存储到随机访问文件或要求输入数据为[]字节类型的其他类型的数据操作等情况。
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转换,您可以参考下面的比较。
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