web-dev-qa-db-fra.com

Comment multiplier une durée par un entier?

Pour tester des goroutines simultanées, j'ai ajouté une ligne à une fonction afin de rendre le retour aléatoire (jusqu'à une seconde).

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

Cependant, quand j'ai compilé, j'ai eu cette erreur

.\crawler.go: 49: opération non valide: Rand.Int31n (1000) * time.Millisecond (types incompatibles int32 et time.Duration)

Des idées? Comment puis-je multiplier une durée?

216
Colonel Panic

int32 et time.Duration sont de types différents. Vous devez convertir le int32 en time.Duration, tel que time.Sleep(time.Duration(Rand.Int31n(1000)) * time.Millisecond).

326
mna

Vous devez le lancer dans un format correct Playground.

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

Si vous vérifiez la documentation pour veille , vous constatez que celle-ci requiert la valeur de func Sleep(d Duration) duration. Votre Rand.Int31n renvoie int32.

La ligne de l'exemple fonctionne (time.Sleep(100 * time.Millisecond)) car le compilateur est suffisamment intelligent pour comprendre qu'ici votre constante 100 signifie une durée. Mais si vous passez une variable, vous devriez la lancer.

42
Salvador Dali

Dans Go, vous pouvez multiplier les variables du même type, vous devez donc avoir les deux parties de l'expression du même type.

La chose la plus simple que vous puissiez faire est de convertir un entier en durée avant de se multiplier, mais cela violerait la sémantique d'unité. Quelle serait la multiplication de la durée par la durée en termes d'unités?

Je préfère convertir time.Milliseconde en int64, puis le multiplier par le nombre de millisecondes, puis le transtyper en time.Duration:

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

De cette façon, toute partie de l'expression peut être considérée comme ayant une valeur significative en fonction de son type. int64(time.Millisecond) une partie n'est qu'une valeur sans dimension - le nombre d'unités de temps les plus petites dans la valeur d'origine.

Si marcher un chemin un peu plus simple:

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

La partie gauche de la multiplication est absurde - une valeur de type "time.Duration", contenant quelque chose de non pertinent pour son type:

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

Et il ne s’agit pas que de la sémantique, il existe une fonctionnalité réelle associée aux types. Ce code imprime:

100ns
100ms

Fait intéressant, l'exemple de code utilisé ici utilise le code le plus simple, avec la même sémantique trompeuse de conversion de durée: https://golang.org/pkg/time/#Duration

secondes: = 10

fmt.Print (time.Duration (seconds) * time.Second) // affiche 10 secondes

10
George Polevoy