2016-05-17 12 views
1

Ich benutze eine 2D-Scheibe von Bytes, um eine Reihe von Linien darzustellen, aber wenn ich an eine der Linien anhänge, bekomme ich sehr seltsames Verhalten. HierSeltsames Verhalten beim Anhängen an eine 2d-Schicht

ein Beispiel:

package main 

import (
    "bytes" 
    "fmt" 
) 

func main() { 
    str := []byte("first line\nsecond line\nthird line") 
    values := bytes.Split(str, []byte("\n")) 

    fmt.Println("Before:") 
    fmt.Println(string(values[0])) 
    fmt.Println(string(values[1])) 
    fmt.Println(string(values[2])) 
    fmt.Println() 

    values[0] = append(values[0], []byte("-inserted text-")...) 

    fmt.Println("After:") 
    fmt.Println(string(values[0])) 
    fmt.Println(string(values[1])) 
    fmt.Println(string(values[2])) 
} 

ich die Ausgabe dieses Programms erwarten

Before: 
first line 
second line 
third line 

After: 
first line-inserted text- 
second line 
third line 

Aber anstatt die Ausgabe sein:

Before: 
first line 
second line 
third line 

After: 
first line-inserted text- 
inserted te 
t-ird line 

https://play.golang.org/p/iNw6s1S66U

Warum passiert das und wie kann ich das beheben?

Interessanterweise geschieht dies nicht, wenn ich Werte nicht Split verwenden und stattdessen definieren wie folgt:

values := [][]byte{[]byte("first line"), []byte("second line"), []byte("third line")} 

https://play.golang.org/p/pEflrhKLd4

Antwort

2

Der zugrunde liegende Speicher ist freigegeben. Um also den gewünschten Effekt zu erzielen, müssen Sie Kopien der von bytes.Split zurückgegebenen Slices speichern und nicht nur die zurückgegebenen Slices. Wenn Sie an das erste zurückgegebene Segment anhängen, stampfen Sie im Wesentlichen über die folgenden Slices hinweg.

+0

Wenn Sie sagen, der Speicher ist geteilt, was meinst du? Beziehen Sie sich auf die Elemente der Scheibe hintereinander aufgereiht? – AJPennster

+0

Das valriable 'str' ist ein Byte-Slice mit einer gewissen Menge an Backend-Speicher. Dann gibt 'byte.Slice' eine Scheibe von [] Byte zurück, die alle auf den gleichen Hintergrundspeicher zeigen. Sie zeigen also alle (zu Beginn) in denselben gemeinsamen Speicher. – Vatine

+0

Rechts. Ich konnte es bestätigen. – AJPennster

1

Was Sie tun, um die Zeichenfolge anhängt, statt Anhängen an das Array und das Überlaufen der zugrunde liegenden Datenstruktur für die Scheibe. Aus diesem Grund wird der Rest des Arrays mit der Zeichenfolge überschrieben, die Sie anhängen.

Um zu klären (dies nicht immer der Fall sein kann):

das Array values besteht aus 3 [] Byte-Blöcke nacheinander aufgereiht. Jeder [] Byteblock hat eine feste Länge (basierend auf der Länge des darin enthaltenen Strings). So hat values[0] eine Länge von 10 (ausschließlich '\ n' oder '\ 0'). Wenn Sie jetzt versuchen, diesen Block mit "-inserted text-" anzufügen, "fließen" die Zeichen in den fortlaufenden Block values[1] und ersetzen die Zeichen in values[1] durch die Zeichen in "-inserted text-". Deshalb sehen Sie Teile dieser Zeichen innerhalb von values[1] und values[1].