英文:
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 
copyfunction 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, 
copywill 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论