Odpowiedzi:
Bezpieczny i prosty:
[]byte("Here is a string....")
[]byte("one", "two")
?
Aby przekonwertować ciąg na plasterek bajtowy string -> []byte
:
[]byte(str)
Aby przekonwertować tablicę na plasterek [20]byte -> []byte
:
arr[:]
Aby skopiować ciąg do tablicy string -> [20]byte
:
copy(arr[:], str)
To samo co powyżej, ale najpierw najpierw jawnie konwertuje ciąg na plasterek:
copy(arr[:], []byte(str))
copy
funkcja kopiuje tylko do plasterka, z plasterka.[:]
powoduje, że tablica kwalifikuje się jako plasterek.copy
skopiuje tylko część pasującą do łańcucha.Ten kod:
var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)
... daje następujący wynik:
array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)
Udostępniłem go również na Go Playground
b[i] = []byte("A")[0]
działa, ale w b[i] = 'A'
końcu jest o wiele czystsze.
b[1] = '本'
Na przykład,
package main
import "fmt"
func main() {
s := "abc"
var a [20]byte
copy(a[:], s)
fmt.Println("s:", []byte(s), "a:", a)
}
Wynik:
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
, funkcja `copy nie jest głupia. Dołączanie i kopiowanie plasterków : „Liczba skopiowanych elementów to minimum len (src) i len (dst)”.
Bułka z masłem:
arr := []byte("That's all folks!!")
[]byte
jest lepsze niż tablice [20]byte
. Odpowiedź jest poprawna w oparciu o najlepsze praktyki; jeśli specyfikacja lub kod wymaga tablic, użyj copy
zamiast tego (zobacz przykłady w innym miejscu tego wątku).
Myślę że to jest lepsze..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
Sprawdź tutaj: http://play.golang.org/p/vpnAWHZZk7
Potrzebujesz szybkiego sposobu konwersji ciągu [] na typ bajtu []. Do użycia w sytuacjach, takich jak przechowywanie danych tekstowych w pliku o swobodnym dostępie lub innego rodzaju manipulowanie danymi, które wymaga, aby dane wejściowe były typu [] bajtowego.
package main
func main() {
var s string
//...
b := []byte(s)
//...
}
co jest przydatne podczas korzystania z ioutil.WriteFile, który przyjmuje wycinek bajtów jako parametr danych:
WriteFile func(filename string, data []byte, perm os.FileMode) error
Inny przykład
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)))
}
Wynik:
[104 101 108 108 111 32 119 111 114 108 100] witaj świecie
Proszę sprawdzić link plac zabaw
Skończyło się tworzenie metod specyficznych dla tablicy, aby to zrobić. Podobnie jak pakiet kodowania / binarny z określonymi metodami dla każdego typu int. Na przykład 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)
Wynik:
[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]
Zwróć uwagę, jak chciałem dopełnienie po lewej, a nie po prawej.
byte16PutString
implementacją wbudowanej copy
funkcji, która obsługuje tylko tworzenie nowych tablic zamiast korzystania z istniejącej. copy
ma specjalną obsługę kompilatora, dzięki czemu może obsługiwać różne typy argumentów i prawdopodobnie ma naprawdę wydajną implementację pod przykryciem. Poza tym pytanie OP dotyczyło napisania ciągu do istniejącej tablicy, a nie przydzielenia nowego, chociaż większość innych odpowiedzi wydaje się też ignorować to ...
answer
jest poprawne, każde ciało jest tutaj, aby uczyć się i zachęcać innych
Oprócz metod wymienionych powyżej, możesz także zrobić trick
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Idź Graj: http://play.golang.org/p/xASsiSpQmC
Nigdy nie powinieneś tego używać :-)
[]byte
obiektu za pomocą swojej „konwersji” - nie udaje się to przy próbie zmiany p
, patrz: play.golang.org/p/WHGl756ucj . W twoim przypadku nie wiesz, dlaczego wolisz podwójne niebezpieczne od b := []byte(s)
metody.
cap()
dowolną wielkość, co oznacza, że wczytuje się w nieznaną pamięć. Aby było to poprawne, myślę, że musisz upewnić się, że przydzielono pełny reflect.SliceHeader
rozmiar i ręcznie ustawiłeś cap
. Coś w tym stylu: play.golang.org/p/fBK4dZM-qD
Tablice są wartościami ... plasterki bardziej przypominają wskaźniki. To [n]type
nie jest zgodne, []type
ponieważ są to zasadniczo dwie różne rzeczy. Możesz uzyskać wycinek, który wskazuje tablicę, używając tego, arr[:]
który zwraca wycinek, który ma arr
jako pamięć zapasową.
Jednym ze sposobów, aby przekształcić plasterek na przykład []byte
na [20]byte
to, aby rzeczywiście lokować [20]byte
które można zrobić przy użyciu var [20]byte
(jak jest to wartość ... nie make
jest to konieczne), a następnie skopiować dane do niego:
buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)
Zasadniczo błędem jest wiele innych odpowiedzi, że []type
NIE jest to tablica.
[n]T
i []T
są zupełnie innymi rzeczami!
Podczas używania odbicia []T
nie jest to rodzaj Array, ale rodzaj Slice i [n]T
jest to rodzaj Array.
Ty też nie możesz używać, map[[]byte]T
ale możesz używać map[[n]byte]T
.
Czasami może to być kłopotliwe, ponieważ wiele funkcji działa na przykład podczas, []byte
gdy niektóre funkcje powracają [n]byte
(w szczególności funkcje skrótu w crypto/*
). Na przykład skrót mieszający sha256 jest [32]byte
i nie jest []byte
tak, gdy początkujący próbują zapisać go na przykład w pliku:
sum := sha256.Sum256(data)
w.Write(sum)
dostaną błąd. Prawidłowym sposobem jest użycie
w.Write(sum[:])
Czego jednak chcesz? Tylko dostęp do łańcucha znaków w inny sposób? Możesz łatwo przekonwertować a string
na []byte
:
bytes := []byte(str)
ale to nie jest tablica, to kawałek. Również byte
! = rune
. Jeśli chcesz operować na „postaciach”, musisz użyć rune
… nie byte
.
str
jest większa niż długośćarr
, pojawi się błąd „indeks poza zakresem”.