ฉันต้องการกำหนดสตริงให้กับอาร์เรย์ไบต์:
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]T
map[[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
คุณจะได้รับข้อผิดพลาด "ดัชนีอยู่นอกช่วง"