Es ist schön, dass Go einen Duration
Typ hat - explizit definierte Einheiten können reale Probleme verhindern.
Und aufgrund der strengen Typregeln von Go können Sie eine Dauer nicht mit einer Ganzzahl multiplizieren. Sie müssen eine Umwandlung verwenden, um allgemeine Typen zu multiplizieren.
/*
MultiplyDuration Hide semantically invalid duration math behind a function
*/
func MultiplyDuration(factor int64, d time.Duration) time.Duration {
return time.Duration(factor) * d // method 1 -- multiply in 'Duration'
// return time.Duration(factor * int64(d)) // method 2 -- multiply in 'int64'
}
Die offizielle Dokumentation zeigt die Verwendung von Methode 1:
Um eine ganzzahlige Anzahl von Einheiten in eine Dauer umzuwandeln, multiplizieren Sie:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
Aber das Multiplizieren einer Dauer mit einer Dauer sollte natürlich keine Dauer ergeben - das ist auf den ersten Blick unsinnig. In diesem Fall werden 5 Millisekunden mal 5 Millisekunden erzeugt 6h56m40s
. Der Versuch, 5 Sekunden zu quadrieren, führt zu einem Überlauf (und wird nicht einmal kompiliert, wenn Konstanten verwendet werden).
Übrigens begrenzt die int64
Darstellung Duration
in Nanosekunden "die größte darstellbare Dauer auf ungefähr 290 Jahre" , und dies zeigt an, dass Duration
wie int64
ein vorzeichenbehafteter Wert behandelt wird: (1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
und genau so wird es implementiert:
// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64
Also, weil wir wissen, dass die zugrunde liegende Darstellung von Duration
ein int64
ist, das Casting zwischen int64
und Duration
ein vernünftiges NO-OP ist - nur erforderlich, um Sprachregeln über das Mischen von Typen zu erfüllen, und es hat keine Auswirkung auf die nachfolgende Multiplikationsoperation.
Wenn Ihnen das Casting aus Gründen der Reinheit nicht gefällt, begraben Sie es in einem Funktionsaufruf, wie ich oben gezeigt habe.
rand.Seed(time.Now().Unix())