Câu trả lời:
An toàn và đơn giản:
[]byte("Here is a string....")
[]bytevà không phải là một mảng byte được thiết lập [20]bytekhi 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))
copychỉ 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.copysẽ 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 copythay 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.
byte16PutStringnó là một dạng tái hiện của copyhà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ó. copycó 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 đó ...
answerlà 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.SliceHeaderkí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]typekhông tương thích []typevì 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ó arrlưu trữ dự phòng.
Một cách để chuyển đổi một lát ví dụ []byteđể [20]bytelà để thực sự phân bổ một [20]bytemà bạn có thể làm bằng cách sử dụng var [20]byte(như đó là một giá trị ... không makecầ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 []typelà KHÔNG phải là một mảng.
[n]Tvà []Tlà những thứ hoàn toàn khác nhau!
Khi sử dụng phản chiếu []Tkhông phải là loại Array mà là loại Slice và [n]Tlà loại Array.
Bạn cũng không thể sử dụng map[[]byte]Tnhư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 []bytetrong 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]bytevà không phải []bytevậ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 stringsang []bytesử 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.
strlớn hơn độ dàiarrthì bạn sẽ gặp lỗi "chỉ số nằm ngoài phạm vi".