Yanıtlar:
Güvenli ve basit:
[]byte("Here is a string....")
[]byte("one", "two")
?
Bir dizeden bayt dilimine dönüştürmek için string -> []byte
:
[]byte(str)
Bir diziyi bir dilime dönüştürmek için [20]byte -> []byte
:
arr[:]
Bir dizeyi diziye kopyalamak için string -> [20]byte
:
copy(arr[:], str)
Yukarıdaki ile aynı, ancak dizeyi açıkça bir dilime dönüştürüyoruz:
copy(arr[:], []byte(str))
copy
işlevi yalnızca kopyaları için bir dilim, gelen bir dilim.[:]
, bir diziyi dilim olarak nitelendirir.copy
dizenin yalnızca uygun olan kısmını kopyalar.Bu kod:
var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)
... şu çıktıyı verir:
array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)
Ben ayrıca bu hazır Git Playground
b[i] = []byte("A")[0]
yaradı, ama b[i] = 'A'
çok daha temiz olur.
b[1] = '本'
Örneğin,
package main
import "fmt"
func main() {
s := "abc"
var a [20]byte
copy(a[:], s)
fmt.Println("s:", []byte(s), "a:", a)
}
Çıktı:
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
, `kopyalama işlevi aptal değil. Dilimlere ekleme ve kopyalama : "Kopyalanan öğelerin sayısı en az len (src) ve len (dst) 'dir."
Kekin parçası:
arr := []byte("That's all folks!!")
[]byte
kullanılması tercih edilir [20]byte
. En iyi uygulamalara göre cevap doğrudur; teknik özellikler veya kod diziler gerektiriyorsa, copy
bunun yerine kullanın (bu iş parçacığının başka yerlerindeki örneklere bakın).
Bence bu daha iyi..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
Buraya bakın: http://play.golang.org/p/vpnAWHZZk7
[] Dizesini [] bayt türüne dönüştürmenin hızlı bir yoluna ihtiyacınız vardır. Metin verilerinin rasgele erişim dosyasına veya giriş verilerinin [] bayt tipinde olmasını gerektiren başka bir veri işleme türü gibi durumlarda kullanmak için.
package main
func main() {
var s string
//...
b := []byte(s)
//...
}
veri parametresi olarak bir bayt dilimini kabul eden ioutil.WriteFile kullanılırken yararlıdır:
WriteFile func(filename string, data []byte, perm os.FileMode) error
Başka bir örnek
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)))
}
Çıktı:
[104101108101111 3211111111410100] Merhaba dünya
Lütfen bağlantı oyun alanını kontrol edin
Bunu yapmak için diziye özgü yöntemler oluşturma sona erdi. Her int türü için özel yöntemlerle kodlama / ikili pakete çok benzer . Örneğin 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)
Çıktı:
[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]
Solda nasıl doldurmak istediğime dikkat edin, sağda değil.
byte16PutString
yerleşik copy
fonksiyonun bir tür yeniden uygulanması , çünkü sadece mevcut bir dizini kullanmak yerine yeni diziler oluşturmayı destekler. copy
özel derleyici desteğine sahiptir, bu nedenle farklı türde argümanları işleyebilir ve muhtemelen kapakların altında gerçekten yüksek performanslı bir uygulamaya sahiptir. Ayrıca, OP'nin sorusu, diğer cevapların çoğu da bunu görmezden geliyor gibi görünse de, yeni bir tane ayırmak yerine mevcut bir diziye bir dize yazma hakkında sorular sordu ...
answer
doğru oy her vücut öğrenmek ve teşvik etmek için burada
Yukarıda belirtilen yöntemlerin yanı sıra,
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Git oyna: http://play.golang.org/p/xASsiSpQmC
Bunu asla kullanmamalısınız :-)
[]byte
"dönüşümünüzü" kullanarak uygun bir nesne elde edemezsiniz - değiştirmeye çalıştığınızda kötü başarısız olur p
, bkz: play.golang.org/p/WHGl756ucj . Sizin durumunuzda, b := []byte(s)
yöntem üzerinde neden çift güvensizliği tercih edeceğinizden emin değilsiniz .
cap()
keyfi bir boyutu var, bu da bilinmeyen belleğe okuduğu anlamına geliyor. Bunun doğru olması için, tam reflect.SliceHeader
boyutu ayırdığınızdan ve manuel olarak ayarladığınızdan emin olmanız gerektiğini düşünüyorum cap
. Bunun gibi bir şey: play.golang.org/p/fBK4dZM-qD
Diziler değerdir ... dilimler daha çok işaretçiler gibidir. Yani [n]type
uyumlu değil []type
temelden farklı şeylerdir olarak. Yedekleme depolama alanı arr[:]
olan bir dilim döndüren bir diziyi işaret eden bir dilim alabilirsiniz arr
.
Örneğin bir dilim dönüştürmek için bir yolu []byte
için [20]byte
aslında bir tahsis etmektir [20]byte
kullanarak yapabileceğiniz hangi var [20]byte
(bir değer olarak ... hayır make
gerekli) ve daha sonra içine veri kopyalamak:
buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)
Aslında diğer cevapların bir çok yanlış yaptığı []type
bir dizi DEĞİLDİR.
[n]T
ve []T
tamamen farklı şeyler!
Yansıtmayı kullanırken []T
tür Array değil, Dilim tür ve [n]T
Array türündedir.
Ayrıca kullanamazsınız map[[]byte]T
ama kullanabilirsiniz map[[n]byte]T
.
Bu bazen hantal olabilir çünkü birçok işlev örneğin üzerinde []byte
çalışırken, bazı işlevler geri döner [n]byte
(en önemlisi hash işlevleri crypto/*
). Örneğin bir sha256 karması , yeni başlayanlar örneğin bir dosyaya yazmaya çalıştığında [32]byte
değildir []byte
:
sum := sha256.Sum256(data)
w.Write(sum)
bir hata alırlar. Doğru yolu kullanmak
w.Write(sum[:])
Ancak, ne istiyorsunuz? Sadece dizeye yavaş yavaş mı erişiyorsunuz? Kolayca bir dönüştürebilirsiniz string
için []byte
kullanıyor:
bytes := []byte(str)
ama bu bir dizi değil, bir dilim. Ayrıca byte
,! = rune
. "Karakterler" üzerinde çalışmak istemeniz durumunda rune
... kullanmanız gerekmiyor byte
.
str
büyükse,arr
"aralık dışında bir dizin" hatası alırsınız.