Konvertieren Sie das Array in Go in Slice

73

Dies scheint , wie es eine ziemlich gemeinsame Sache und reichlich Beispiele für die interwebs sein würde, aber ich kann nicht ein Beispiel zu finden scheinen , wie ein konvertieren [32]bytezu []byte.

Ich habe eine Funktion, die ich von einer externen Bibliothek aufrufe, die ein Array zurückgibt

func Foo() [32]byte {...}

Ich muss dieses Ergebnis dann zur weiteren Verarbeitung an eine andere Funktion übergeben.

func Bar(b []byte) { ... }

Leider, wenn ich versuche anzurufen

d := Foo()
Bar(d)

Ich bekomme

cannot convert d (type [32]byte) to type []byte

Tun

[]byte(d)

ist nicht viel besser. Wie mache ich das, insbesondere ohne eine Kopie der Daten zu erstellen (es scheint albern, diese Daten zu kopieren, wenn ich sie nur weitergebe).

FuriousGeorge
quelle
4
Siehe blog.golang.org/slices
Dave C

Antworten:

110

Das sollte funktionieren:

func Foo() [32]byte {
    return [32]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}
}

func Bar(b []byte) {
    fmt.Println(string(b))
}

func main() {
    x := Foo()
    Bar(x[:])
}

Und es wird keine Kopie des zugrunde liegenden Puffers erstellt

Not_a_Golfer
quelle
2
Ist es möglich, einen Oneliner zum Bar(Foo()[:])Arbeiten zu bringen?
BluBb_mADe
2
@BluBb_mADe Nr. Ein Slice ist im Grunde eine Struktur unter der Decke mit zugrunde liegenden Verweisen auf: einen Puffer; seine Länge; und seine Kapazität. Um den Puffer eines Slice zu initialisieren, benötigt man adressierbaren Speicher vom Heap, nicht vom Stapel (wo Rückgabewerte gespeichert sind), da der Stapelspeicher außerhalb seiner Funktion nicht persistent ist. Es ist aus dem gleichen Grund kann man nicht so etwas wie tun dies .
colm.anseo
3
na ja, warum müssen diese Dinge immer so logisch sein.
BluBb_mADe
59
arr[:]  // arr is an array; arr[:] is the slice of all elements
Jamesfischer
quelle
10

Dies wird den Trick machen:

slice := array[0:len(array)]

Vermeidet auch das Kopieren des zugrunde liegenden Puffers.

bowsky
quelle
5
Der Standardwert für die Untergrenze ist 0. Der Standardwert für die Obergrenze ist len(x)also x[0:len(x)]besser geschrieben als x[:]. Welches ist genau das, was die vorhandene Antwort sagt.
Dave C
12
Ich finde die Anzahl der Abstimmungen angesichts der Gültigkeit der Lösung etwas hart ...
Mike Gleason jr. Couturier
1
Obwohl das OP nur eine vollständige Konvertierung des zugrunde liegenden Arrays wünschte, ist es hilfreich zu wissen, dass die Angabe der Untergrenze und der Obergrenze mit der Slice-Annotation identisch ist. Beispielsweise möchten Sie möglicherweise ein Array zuweisen (anstatt make Slice zu verwenden) und dann Teile des Arrays in der Notation für die untere / obere Grenze festlegen. Beispiel: play.golang.org/p/BwIvavioBj
Bill Katz
4

Sie können ein Array im Allgemeinen nach seinen Grenzen aufteilen mit ::

var a [32]byte 
slice := a[:]

Allgemeiner für das folgende Array:

var my_array [LENGTH]TYPE

Sie können die Scheibe in verschiedenen Größen herstellen, indem Sie Folgendes schreiben:

my_array[START_SLICE:END_SLICE]

Auslassen, START_SLICEwenn es der Untergrenze entspricht und END_SLICEwenn es der Obergrenze entspricht , in Ihrem Fall:

a[0:32] 

Erzeugt das Slice des zugrunde liegenden Arrays und entspricht:

a[0:]
a[:32]
a[:]
Ismail H.
quelle