Câu trả lời:
An toàn và đơn giản:
[]byte("Here is a string....")
[]byte
và không phải là một mảng byte được thiết lập [20]byte
khi chuyển đổi chuỗi thành byte ... Bạn có tin tôi không? Kiểm tra câu trả lời của Rob Pike về chủ đề này
[]byte("one", "two")
?
Để chuyển đổi từ một chuỗi thành một lát byte , string -> []byte
:
[]byte(str)
Để chuyển đổi một mảng thành một lát , [20]byte -> []byte
:
arr[:]
Để sao chép một chuỗi vào một mảng , string -> [20]byte
:
copy(arr[:], str)
Tương tự như trên, nhưng trước tiên chuyển đổi chuỗi thành một lát:
copy(arr[:], []byte(str))
copy
chỉ sao chép vào một lát, từ một lát.[:]
làm cho một mảng đủ điều kiện là một lát.copy
sẽ chỉ sao chép phần của chuỗi phù hợp.Mã này:
var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)
... Cho đầu ra sau:
array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)
Tôi cũng đã làm cho nó có sẵn tại Sân chơi Go
b[i] = []byte("A")[0]
hoạt động, nhưng b[i] = 'A'
cuối cùng sạch sẽ hơn nhiều.
b[1] = '本'
Ví dụ,
package main
import "fmt"
func main() {
s := "abc"
var a [20]byte
copy(a[:], s)
fmt.Println("s:", []byte(s), "a:", a)
}
Đầu ra:
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]
s
, Hàm `copy không bị câm. Nối và sao chép các lát : "Số phần tử được sao chép là tối thiểu của len (src) và len (dst)."
Miếng bánh:
arr := []byte("That's all folks!!")
[]byte
được ưa thích hơn mảng [20]byte
. Trả lời là đúng dựa trên thực tiễn tốt nhất; nếu thông số kỹ thuật hoặc mã yêu cầu mảng, sau đó sử dụng copy
thay thế (xem ví dụ ở nơi khác trong chuỗi này).
Tôi nghĩ nó tốt hơn..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
Kiểm tra tại đây: http://play.golang.org/p/vpnAWHZZk7
Bạn cần một cách nhanh chóng để chuyển đổi một chuỗi [] thành [] kiểu byte. Để sử dụng trong các tình huống như lưu trữ dữ liệu văn bản vào tệp truy cập ngẫu nhiên hoặc loại thao tác dữ liệu khác yêu cầu dữ liệu đầu vào phải ở dạng byte [].
package main
func main() {
var s string
//...
b := []byte(s)
//...
}
hữu ích khi sử dụng ioutil.WriteFile, chấp nhận một lát byte làm tham số dữ liệu của nó:
WriteFile func(filename string, data []byte, perm os.FileMode) error
Một vi dụ khac
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)))
}
Đầu ra:
[104 101 108 108 111 32 119 111 114 108 100] xin chào thế giới
Vui lòng kiểm tra sân chơi liên kết
Đã kết thúc việc tạo ra các phương thức cụ thể mảng để làm điều này. Giống như gói mã hóa / nhị phân với các phương thức cụ thể cho từng loại int. Ví dụ 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)
Đầu ra:
[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]
Chú ý cách tôi muốn đệm ở bên trái, không phải bên phải.
byte16PutString
nó là một dạng tái hiện của copy
hàm dựng sẵn , chỉ hỗ trợ tạo các mảng mới thay vì sử dụng một mảng hiện có. copy
có hỗ trợ trình biên dịch đặc biệt, vì vậy nó có thể xử lý các loại đối số khác nhau và có lẽ nó có một triển khai hiệu năng thực sự cao dưới vỏ bọc. Ngoài ra, câu hỏi của OP đã hỏi về việc viết một chuỗi vào một mảng hiện có, thay vì phân bổ một chuỗi mới, mặc dù hầu hết các câu trả lời khác dường như cũng bỏ qua điều đó ...
answer
là chính xác, mọi người đều ở đây để học hỏi và khuyến khích người khác
Bên cạnh các phương pháp được đề cập ở trên, bạn cũng có thể thực hiện một mẹo như
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Chơi: http://play.golang.org/p/xASsiSpQmC
Bạn không bao giờ nên sử dụng cái này :-)
[]byte
đối tượng phù hợp bằng cách sử dụng "chuyển đổi" của mình - nó thất bại nặng nề khi bạn cố gắng sửa đổi p
, xem: play.golang.org/p/WHGl756ucj . Trong trường hợp của bạn, không chắc chắn lý do tại sao bạn thích không an toàn gấp đôi so với b := []byte(s)
phương pháp.
cap()
kích thước tùy ý, có nghĩa là nó đọc vào bộ nhớ không xác định. Để điều này đúng, tôi nghĩ bạn cần đảm bảo rằng bạn phân bổ reflect.SliceHeader
kích thước đầy đủ và đặt thủ công cap
. Một cái gì đó như thế này: play.golang.org/p/fBK4dZM-qD
Mảng là giá trị ... lát giống như con trỏ. Điều đó [n]type
không tương thích []type
vì về cơ bản chúng là hai thứ khác nhau. Bạn có thể nhận được một lát chỉ đến một mảng bằng cách sử dụng arr[:]
trả về một lát có arr
lưu trữ dự phòng.
Một cách để chuyển đổi một lát ví dụ []byte
để [20]byte
là để thực sự phân bổ một [20]byte
mà bạn có thể làm bằng cách sử dụng var [20]byte
(như đó là một giá trị ... không make
cần thiết) và sau đó sao chép dữ liệu vào nó:
buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)
Về cơ bản, rất nhiều câu trả lời khác bị sai []type
là KHÔNG phải là một mảng.
[n]T
và []T
là những thứ hoàn toàn khác nhau!
Khi sử dụng phản chiếu []T
không phải là loại Array mà là loại Slice và [n]T
là loại Array.
Bạn cũng không thể sử dụng map[[]byte]T
nhưng bạn có thể sử dụng map[[n]byte]T
.
Điều này đôi khi có thể cồng kềnh vì rất nhiều hàm hoạt động chẳng hạn []byte
trong khi một số hàm trả về [n]byte
(đáng chú ý nhất là các hàm băm trong crypto/*
). Ví dụ, hàm băm sha256 là như vậy [32]byte
và không phải []byte
vậy khi người mới bắt đầu cố gắng ghi nó vào một tệp chẳng hạn:
sum := sha256.Sum256(data)
w.Write(sum)
họ sẽ nhận được một lỗi. Cách chính xác là sử dụng
w.Write(sum[:])
Tuy nhiên, đó là những gì bạn muốn? Chỉ cần truy cập chuỗi bytewise? Bạn có thể dễ dàng chuyển đổi string
sang []byte
sử dụng:
bytes := []byte(str)
nhưng đây không phải là một mảng, nó là một lát cắt. Ngoài ra , byte
! = rune
. Trong trường hợp bạn muốn thao tác trên "ký tự", bạn cần sử dụng rune
... không byte
.
str
lớn hơn độ dàiarr
thì bạn sẽ gặp lỗi "chỉ số nằm ngoài phạm vi".