英文:
How to assign string to bytes array
问题
我想将字符串赋值给字节数组:
var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
arr[k] = byte(v)
}
还有其他方法吗?
英文:
I want to assign string to bytes array:
var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
arr[k] = byte(v)
}
Have another method?
答案1
得分: 730
安全且简单:
[]byte("这是一个字符串....")
英文:
Safe and simple:
[]byte("Here is a string....")
答案2
得分: 255
将字符串转换为字节切片,string -> []byte
:
[]byte(str)
将数组转换为切片,[20]byte -> []byte
:
arr[:]
将字符串复制到数组,string -> [20]byte
:
copy(arr[:], str)
与上面相同,但显式地先将字符串转换为切片:
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)
我还在Go Playground上提供了这段代码。
英文:
For converting from a string to a byte slice, string -> []byte
:
[]byte(str)
For converting an array to a slice, [20]byte -> []byte
:
arr[:]
For copying a string to an array, string -> [20]byte
:
copy(arr[:], str)
Same as above, but explicitly converting the string to a slice first:
copy(arr[:], []byte(str))
- The built-in
copy
function only copies to a slice, from a slice. - Arrays are "the underlying data", while slices are "a viewport into underlying data".
- Using
[:]
makes an array qualify as a slice. - A string does not qualify as a slice that can be copied to, but it qualifies as a slice that can be copied from (strings are immutable).
- If the string is too long,
copy
will only copy the part of the string that fits (and multi-byte runes may then be copied only partly, which will corrupt the last rune of the resulting string).
This code:
var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)
...gives the following output:
array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)
I also made it available at the Go Playground
答案3
得分: 122
例如,
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]
英文:
For example,
package main
import "fmt"
func main() {
s := "abc"
var a [20]byte
copy(a[:], s)
fmt.Println("s:", []byte(s), "a:", a)
}
Output:
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]
答案4
得分: 45
arr := []byte("就这些了伙计们!!")
英文:
Piece of cake:
arr := []byte("That's all folks!!")
答案5
得分: 31
我认为这样更好..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'", mySlice, mySlice)
}
在这里查看:http://play.golang.org/p/vpnAWHZZk7
英文:
I think it's better..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
Check here: http://play.golang.org/p/vpnAWHZZk7
答案6
得分: 15
Go,将字符串转换为字节切片
您需要一种快速将[]string转换为[]byte类型的方法。在需要将文本数据存储到随机访问文件或其他需要输入数据为[]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, " ")
// 字节数组值
fmt.Println([]byte(stringByte))
// 对应的字符串值
fmt.Println(string([]byte(stringByte)))
}
输出:
[104 101 108 108 111 32 119 111 114 108 100] hello world
请查看链接playground
英文:
Go, convert a string to a bytes slice
You need a fast way to convert a []string to []byte type. To use in situations such as storing text data into a random access file or other type of data manipulation that requires the input data to be in []byte type.
package main
func main() {
var s string
//...
b := []byte(s)
//...
}
which is useful when using ioutil.WriteFile, which accepts a bytes slice as its data parameter:
WriteFile func(filename string, data []byte, perm os.FileMode) error
Another example
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)))
}
Output:
> [104 101 108 108 111 32 119 111 114 108 100] hello world
Please check the link playground
答案7
得分: 1
除了上面提到的方法,你还可以使用一个技巧:
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Go Play: http://play.golang.org/p/xASsiSpQmC
你永远不应该使用这个方法
英文:
Besides the methods mentioned above, you can also do a trick as
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Go Play: http://play.golang.org/p/xASsiSpQmC
You should never use this
答案8
得分: 1
Ended up creating array specific methods to do this. Much like the encoding/binary package with specific methods for each int type. For example 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)
Output:
[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]
Notice how I wanted padding on the left, not the right.
http://play.golang.org/p/7tNumnJaiN
英文:
Ended up creating array specific methods to do this. Much like the encoding/binary package with specific methods for each int type. For example 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)
Output:
[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]
Notice how I wanted padding on the left, not the right.
答案9
得分: 1
数组是值...切片更像是指针。也就是说,[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
是完全不同的东西!
在使用反射时,[]T
的种类不是数组,而是切片,而[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
。
英文:
Arrays are values... slices are more like pointers. That is [n]type
is not compatible with []type
as they are fundamentally two different things. You can get a slice that points to an array by using arr[:]
which returns a slice that has arr
as it's backing storage.
One way to convert a slice of for example []byte
to [20]byte
is to actually allocate a [20]byte
which you can do by using var [20]byte
(as it's a value... no make
needed) and then copy data into it:
buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)
Essentially what a lot of other answers get wrong is that []type
is NOT an array.
[n]T
and []T
are completely different things!
When using reflect []T
is not of kind Array but of kind Slice and [n]T
is of kind Array.
You also can't use map[[]byte]T
but you can use map[[n]byte]T
.
This can sometimes be cumbersome because a lot of functions operate for example on []byte
whereas some functions return [n]byte
(most notably the hash functions in crypto/*
).
A sha256 hash for example is [32]byte
and not []byte
so when beginners try to write it to a file for example:
sum := sha256.Sum256(data)
w.Write(sum)
they will get an error. The correct way of is to use
w.Write(sum[:])
However, what is it that you want? Just accessing the string bytewise? You can easily convert a string
to []byte
using:
bytes := []byte(str)
but this isn't an array, it's a slice. Also, byte
!= rune
. In case you want to operate on "characters" you need to use rune
... not byte
.
答案10
得分: 0
如果有人想要快速进行切片之间的转换,可以参考以下比较。
package demo_test
import (
"testing"
"unsafe"
)
var testStr = "hello world"
var testBytes = []byte("hello world")
// 避免复制数据。
func UnsafeStrToBytes(s string) []byte {
return *(*[]byte)(unsafe.Pointer(&s))
}
// 避免复制数据。
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" -run=none
输出
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
英文:
If someone is looking for a quick <sup>consider use unsafe
</sup> conversion between slices, you can refer to the following comparison.
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" -run=none
output
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论