È bello che Go abbia un Duration
tipo: avere unità esplicitamente definite può prevenire problemi nel mondo reale.
E a causa delle rigide regole di tipo di Go, non è possibile moltiplicare una durata per un numero intero: è necessario utilizzare un cast per moltiplicare i tipi comuni.
/*
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'
}
La documentazione ufficiale dimostra l'utilizzo del metodo n. 1:
Per convertire un numero intero di unità in una durata, moltiplicare:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
Ma, naturalmente, moltiplicare una durata per una durata non dovrebbe produrre una durata - questo è insensato. Caso in questione, produce 5 millisecondi per 5 millisecondi 6h56m40s
. Tentare di quadrare 5 secondi provoca un overflow (e non si compila nemmeno se fatto con costanti).
A proposito, la int64
rappresentazione Duration
in nanosecondi "limita la massima durata rappresentabile a circa 290 anni" , e questo indica che Duration
, come int64
, viene trattato come un valore con segno:, (1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
ed è esattamente così che viene implementato:
// 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
Quindi, poiché sappiamo che la rappresentazione sottostante di Duration
è an int64
, esegue il cast tra int64
ed Duration
è un sensibile NO-OP - richiesto solo per soddisfare le regole del linguaggio sui tipi di miscelazione e non ha alcun effetto sulla successiva operazione di moltiplicazione.
Se non ti piace il casting per motivi di purezza, seppelliscilo in una chiamata di funzione, come ho mostrato sopra.
rand.Seed(time.Now().Unix())