2013-07-10 7 views
119

gleichzeitigen goroutines Um zu testen, habe ich auf eine Funktion, um eine Linie zu ihm eine zufälligen Zeit (bis zu einer Sekunde)Wie multipliziert man die Dauer mit einer Ganzzahl?

time.Sleep(rand.Int31n(1000) * time.Millisecond) 

jedoch zurückkehren dauern, wenn ich zusammengestellt habe ich diesen Fehler

\ crawler.go. 49: ungültige Operation: rand.Int31n (1000) * time.Millisecond (mismatched Typen int32 und time.Duration)

Irgendwelche Ideen? Wie kann ich eine Dauer multiplizieren?

Antwort

175

int32 und time.Duration sind verschiedene Arten. Sie müssen die int32 in eine time.Duration konvertieren, z. B. time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond).

+3

Dank, das funktioniert. Ich habe auch gelernt, über den Zufallszahlengenerator Impfen 'rand.Seed (time.Now(). Unix())' –

+11

nur für mein Wissen, wie funktioniert die folgende Arbeit dann? 'time.sleep (time.Second * 2)' –

+23

Es funktioniert, weil Konstanten einen adaptiven Typ haben, je nachdem, wie sie verwendet werden. Sehen Sie diesen Blog-Beitrag von Rob Pike, der es im Detail erklärt: http://blog.golang.org/constants – mna

18

Sie müssen es in ein korrektes Format Playground umwandeln.

yourTime := rand.Int31n(1000) 
time.Sleep(time.Duration(yourTime) * time.Millisecond) 

Wenn Sie Dokumentation für sleep überprüfen wird, sehen Sie, dass es func Sleep(d Duration) Dauer als Parameter erfordert. Ihr rand.Int31n gibt int32 zurück.

Die Zeile aus dem Beispiel funktioniert (time.Sleep(100 * time.Millisecond)), weil der Compiler intelligent genug ist zu verstehen, dass hier Ihre constant 100 eine Dauer bedeutet. Aber wenn Sie eine Variable übergeben, sollten Sie sie umsetzen.

0

In Go können Sie Variablen des gleichen Typs multiplizieren, daher müssen beide Teile des Ausdrucks den gleichen Typ haben.

Die einfachste Sache, die Sie tun können, besteht darin, eine Ganzzahl vor der Multiplikation auf Dauer zu transformieren, aber das würde die Einheitensemantik verletzen. Was wäre die Multiplikation von Dauer und Dauer in Einheiten?

Ich würde eher konvertieren time.Millisecond zu einem int64, und dann durch die Anzahl der Millisekunden multiplizieren, dann werfen zu time.Duration:

time.Duration(int64(time.Millisecond) * int64(rand.Int31n(1000))) 

diese Weise ein Teil des Ausdrucks gesagt werden kann, um einen sinnvollen Wert nach seinem Typ zu haben. int64(time.Millisecond) Teil ist nur ein dimensionsloser Wert - die Anzahl der kleinsten Zeiteinheiten im ursprünglichen Wert.

Wenn gehen einen etwas einfacheren Weg:

time.Duration(rand.Int31n(1000)) * time.Millisecond 

Der linke Teil der Multiplikation ist Unsinn - ein Wert vom Typ "time.Duration", etwas irrelevant seiner Art hält:

numberOfMilliseconds := 100 
// just can't come up with a name for following: 
someLHS := time.Duration(numberOfMilliseconds) 
fmt.Println(someLHS) 
fmt.Println(someLHS*time.Millisecond) 

Und es ist nicht nur Semantik, es gibt tatsächliche Funktionalität mit Typen verbunden. Dieser Code druckt:

100ns 
100ms 

Interessanterweise hier das Codebeispiel verwendet den einfachstenen Code, mit der gleichen irreführenden Semantik von Dauer-Konvertierung: https://golang.org/pkg/time/#Duration

Seconds: = 10

fmt.Print (time.Duration (Sekunden) * time.Second) // druckt 10s

Verwandte Themen