2017-08-29 1 views
-2

diesem Code:-umspannen String slice inkonsistent

import "fmt" 
import "time" 
func main() { 
    string_slice:=[]string{"a","b","c"} 

    for _,s:=range string_slice{ 
     go func(){ 
      time.Sleep(1*time.Second) 
      fmt.Println(s) 
     }() 
    } 

    time.Sleep(3*time.Second) 
} 

erzeugt die Ausgabe "ccc", während dieser Code:

import "fmt" 
func main() { 
    string_slice:=[]string{"a","b","c"} 

    for _,s:=range string_slice{ 
     s="asd" 
     fmt.Println(s) 
    } 
    fmt.Println(string_slice) 
} 

erzeugt die Ausgabe "[abc]"

The Der erste würde vorschlagen, dass für den Bereich über Referenzen (die es nicht sollte) iteriert, und der zweite schlägt vor, dass es über Kopien von Werten iteriert (was es sollte).

Warum produziert der erste nicht die Ausgabe "a b c"?

+1

was der Punkt der zweiten ist? Sie drucken nur die ganze Scheibe, nachdem Sie "" asd "' 3 mal gedruckt haben. https://play.golang.org/p/rNEGrgS3AT – mkopriva

+4

https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables –

+2

https://golang.org/ doc/faq # closures_and_goroutines – JimB

Antwort

0

Wenn Sie goroutine verwenden, müssen Sie davon ausgehen, dass es parallel läuft. Also in diesem Fall könnte 'ccc' auftreten als zu 'bbb' oder 'aaa'

Auf Lauf in 3-mal diesen Code:

for _,s:=range string_slice \\run t0, t1, t2 

Sie sendet für die Ausführung von 3 mal diesen Code:

go func(){ 
    fmt.Println(s) 
}()//send in t0, t1, t2 

So könnte von func() starten in t2, pro Beispiel starten. In diesem Fall wird das Ergebnis 'c c' sein, weil s gleich letzten Wert ist (string_slice [2]).

Die Lösung ist kopier Wert von func params:

for _, s := range string_slice{ 
    go func(x string){ 
     time.Sleep(1*time.Second) 
     fmt.Println(x) 
    }(s) 
} 

oder neuen Wert pro Iteration erstellen

//creating new value per iteration 
for i := range string_slice{ 
    s := string_slice[i] 
    go func(){ 
     time.Sleep(1*time.Second) 
     fmt.Println(s) 
    }() 
} 

Siehe Arbeiten in https://play.golang.org/p/uRD6Qy6xSw

Verwandte Themen