2015-01-20 14 views
6

Mam macierz wielkości bajtów, którą mam po wykonaniu md5.Sum().Dlaczego nie można przekonwertować bajtu [Rozmiar] na ciąg w Go?

data := []byte("testing") 
var pass string 
var b [16]byte 
b = md5.Sum(data) 
pass = string(b) 

Błąd:

cannot convert b (type [16]byte) to type string 

znajdę rozwiązanie w tej problem

Przejdź do:

pass = string(b[:]) 

Ale dlaczego nie można go używać w taki sposób?

pass = string(b) 

Odpowiedz

16

Krótka odpowiedź brzmi, ponieważ specyfikacja Go Language nie pozwala na to.

Cytowanie z Go Language Specification: Conversions:

A non-constant value x can be converted to type T in any of these cases:

  • x is assignable to T .
  • x 's type and T have identical underlying types.
  • x 's type and T are unnamed pointer types and their pointer base types have identical underlying types.
  • x's type and T are both integer or floating point types.
  • x's type and T are both complex types.
  • x is an integer or a slice of bytes or runes and T is a string type.
  • x is a string and T is a slice of bytes or runes.

Specyfikacja pozwala tylko na przekształcenie kawałek bajtów lub runy string, ale nie tablicą bajtów.

Długa odpowiedź

W tablicach Idź i plastry są różne typy. Rozmiar tablicy jest częścią typu.

Plasterki są znacznie bardziej ogólne niż tablice, a konwertowanie tablicy na wycinek reprezentujący tę samą serię wartości jest bardzo proste: arr[:] (i jest również tanie, segment wynikowy będzie udostępniał tablicę jako tablicę pomocniczą, nie realokacja lub kopiowanie zostanie wykonane).

Z tego powodu wszystkie funkcje i wsparcie są dostępne dla plasterków, a nie dla tablic.

Po prostu obraz, który chcesz utworzyć prostą funkcję, która pobiera kawałek (o dowolnej długości) z int liczb i zwraca sumę liczb. Coś takiego:

func sum(s []int) (sum int) { 
    for _, v := range s { 
     sum += v 
    } 
    return 
} 

Jeżeli zdecydujesz się używać tablicy jako dane wejściowe, ponieważ długość jest częścią typu, należy ograniczać użyteczność swojej funkcji, to może potrwać tylko tablice o tej samej długości :

func sum2(s [2]int) (sum int) { 
    for _, v := range s { 
     sum += v 
    } 
    return 
} 

można zadzwonić sum2() tylko z wartościami typu [2]int ale jeśli masz tablicę typu [3]int, ty nie ponieważ te 2 typy są różne! Nie możesz również zadzwonić pod numer sum2(), jeśli masz tylko plaster z int (nie możesz uzyskać dostępu do tablicy kopii). W międzyczasie możesz zadzwonić na swoją funkcję sum() ze wszystkimi plasterkami []int, a jeśli masz tablicę, nadal możesz jej użyć, przekazując arr[:] do swojej funkcji sum().

Uwaga:

Należy również pamiętać, że przekształcenie „Random” plaster bajtów do string najprawdopodobniej nie to, co chcesz, ponieważ „random” plaster bajtów nie może być ważny UTF-8 bajtów sekwencja.

Zamiast użyć pakietu encoding/hex przekonwertować wynik na ciąg szesnastkowy jak ten:

fmt.Println(hex.EncodeToString(b[:])) 
+1

dziękuję za bardzo szczegółową odpowiedź, rozumiem – soapbar