ฉันต้องการกำหนดสตริงให้กับอาร์เรย์ไบต์:
var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
arr[k] = byte(v)
}
มีวิธีอื่นไหม
ฉันต้องการกำหนดสตริงให้กับอาร์เรย์ไบต์:
var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
arr[k] = byte(v)
}
มีวิธีอื่นไหม
คำตอบ:
ปลอดภัยและเรียบง่าย:
[]byte("Here is a string....")
[]byte("one", "two")?
สำหรับการแปลงจากสตริงเป็นไบต์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)
ฉันยังให้บริการที่สนามเด็กเล่นโก
b[i] = []byte("A")[0]ผล แต่b[i] = 'A'จบลงด้วยความสะอาดกว่ามาก
b[1] = '本'
ตัวอย่างเช่น,
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]
sฟังก์ชัน `copy ไม่ได้เป็นใบ้ การผนวกและคัดลอกส่วนข้อมูล : "จำนวนองค์ประกอบที่คัดลอกคือขั้นต่ำของ len (src) และ len (dst)"
เค้กชิ้น:
arr := []byte("That's all folks!!")
[]byteเป็นที่ต้องการมากกว่าอาร์เรย์ [20]byteคำตอบนั้นถูกต้องตามแนวทางปฏิบัติที่ดีที่สุด; ถ้าข้อมูลจำเพาะหรือรหัสจำเป็นต้องใช้อาร์เรย์ให้ใช้copyแทน (ดูตัวอย่างที่อื่นในหัวข้อนี้)
ฉันคิดว่ามันจะดีกว่า ..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
ตรวจสอบที่นี่: http://play.golang.org/p/vpnAWHZZk7
คุณต้องการวิธีที่รวดเร็วในการแปลงสตริง [] เป็น [] ประเภทไบต์ เพื่อใช้ในสถานการณ์ต่าง ๆ เช่นการจัดเก็บข้อมูลข้อความลงในไฟล์การเข้าถึงแบบสุ่มหรือการจัดการข้อมูลประเภทอื่นที่ต้องการให้ข้อมูลอินพุตเป็น [] ชนิดไบต์
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)))
}
เอาท์พุท:
[104 101 108 108 111 32 119 111 114 108 100] สวัสดีชาวโลก
กรุณาตรวจสอบลิงค์สนามเด็กเล่น
จบลงด้วยการสร้างวิธีการเฉพาะของอาร์เรย์เพื่อทำสิ่งนี้ คล้ายกับแพ็คเกจการเข้ารหัส / ไบนารีด้วยวิธีการเฉพาะสำหรับแต่ละชนิด int 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]
สังเกตว่าฉันต้องการแพ็ดดิ้งทางซ้ายไม่ใช่ทางขวา
byte16PutStringการจัดเรียงใหม่ของcopyฟังก์ชั่นbuiltin ที่รองรับเฉพาะการสร้างอาร์เรย์ใหม่แทนที่จะใช้ที่มีอยู่แล้ว copyมีการสนับสนุนคอมไพเลอร์พิเศษดังนั้นจึงสามารถจัดการกับประเภทของข้อโต้แย้งที่แตกต่างกันและอาจมีการใช้งานที่มีประสิทธิภาพสูงจริงๆภายใต้ฝาครอบ นอกจากนี้คำถามของ OP ยังถามเกี่ยวกับการเขียนสตริงไปยังอาร์เรย์ที่มีอยู่แทนที่จะจัดสรรสตริงใหม่แม้ว่าคำตอบอื่น ๆ ส่วนใหญ่ก็ดูเหมือนจะเพิกเฉยเช่นกัน ...
answerถูกต้องทุกคนอยู่ที่นี่เพื่อเรียนรู้และสนับสนุนผู้อื่น
นอกเหนือจากวิธีการที่กล่าวข้างต้นคุณสามารถทำตาม
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
ไปเล่น: http://play.golang.org/p/xASsiSpQmC
คุณไม่ควรใช้ :-) นี้
[]byteวัตถุที่เหมาะสมโดยใช้ "การแปลง" ของคุณ - มันล้มเหลวไม่ดีเมื่อคุณพยายามแก้ไขpดู: play.golang.org/p/WHGl756ucj ในกรณีของคุณไม่แน่ใจว่าทำไมคุณถึงต้องการสองครั้งที่ไม่ปลอดภัยมากกว่าb := []byte(s)วิธีนี้
cap()ขนาดตามอำเภอใจซึ่งหมายความว่ามันอ่านในหน่วยความจำที่ไม่รู้จัก สำหรับเรื่องนี้จะต้องมีสิทธิผมคิดว่าคุณจะต้องให้แน่ใจว่าคุณจัดสรรเต็มรูปแบบขนาดและการตั้งค่าด้วยตนเองreflect.SliceHeader capบางสิ่งเช่นนี้: play.golang.org/p/fBK4dZM-qD
อาร์เรย์เป็นค่า ... ตัวแบ่งเป็นเหมือนตัวชี้ ที่[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]Tmap[[n]byte]T
นี้บางครั้งอาจจะยุ่งยากเพราะมากฟังก์ชั่นการใช้งานตัวอย่างเช่นใน[]byteขณะที่ฟังก์ชั่นบางส่วนจะกลับ[n]byte(ที่สะดุดตาที่สุดในฟังก์ชันแฮชcrypto/*) ตัวอย่างเช่นแฮช sha256 คือ[32]byteและไม่เป็น[]byteเช่นนั้นเมื่อผู้เริ่มต้นพยายามเขียนลงไฟล์เช่น:
sum := sha256.Sum256(data)
w.Write(sum)
พวกเขาจะได้รับข้อผิดพลาด วิธีที่ถูกต้องคือการใช้
w.Write(sum[:])
อย่างไรก็ตามคุณต้องการอะไร เพียงแค่เข้าถึงสตริง bytewise? คุณสามารถแปลงstringไป[]byteใช้:
bytes := []byte(str)
แต่นี่ไม่ใช่อาร์เรย์มันเป็นส่วนแบ่ง นอกจากนี้byte! = rune. ในกรณีที่คุณต้องการที่จะทำงานใน "ตัวละคร" คุณจำเป็นต้องใช้rune... byteไม่ได้
strมากกว่าความยาวของarrคุณจะได้รับข้อผิดพลาด "ดัชนีอยู่นอกช่วง"