回答:
int32
とtime.Duration
異なるタイプです。あなたは、変換する必要があるint32
にtime.Duration
のような、time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
。
time.Sleep(time.Second * 2)
Duration
* Duration
= にキャストする必要がありますDuration
:Duration
* int
= Duration
。
int64(...) * Duration
とDuration
、へのキャストよりも理にかなっています。これは、ユニットがどのように機能するかの基本的な違反です。残念ながらそれはうまくいきません。あなたは本当にDuration * Duration
恐ろしいことをしなければなりません。
正しい形式にキャストする必要がありますPlayground。
yourTime := rand.Int31n(1000)
time.Sleep(time.Duration(yourTime) * time.Millisecond)
ドキュメントのsleepを確認するとfunc Sleep(d Duration)
、パラメータとして期間が必要であることがわかります。あなたのrand.Int31nを返しますint32
。
この例の行は機能します(time.Sleep(100 * time.Millisecond)
)。これは、ここで定数 100が期間を意味することをコンパイラーが理解できるほど賢いためです。ただし、変数を渡す場合は、キャストする必要があります。
Goでは、同じ型の変数を乗算できるため、式の両方の部分を同じ型にする必要があります。
あなたができる最も簡単なことは、乗算する前に整数を期間にキャストすることですが、それはユニットのセマンティクスに違反します。期間の単位による期間の乗算はどうなりますか?
私はむしろtime.Millisecondをint64に変換し、それをミリ秒の数で乗算してから、time.Durationにキャストします。
time.Duration(int64(time.Millisecond) * int64(rand.Int31n(1000)))
このように、式のどの部分も、そのタイプに応じて意味のある値を持つと言えます。int64(time.Millisecond)
部分は、無次元の値です-元の値の時間の最小単位の数。
少し簡単な道を歩く場合:
time.Duration(rand.Int31n(1000)) * time.Millisecond
乗算の左側はナンセンスです-「time.Duration」型の値で、その型とは無関係の何かを保持しています:
numberOfMilliseconds := 100
// just can't come up with a name for following:
someLHS := time.Duration(numberOfMilliseconds)
fmt.Println(someLHS)
fmt.Println(someLHS*time.Millisecond)
そして、それは単なる意味論ではなく、型に関連付けられた実際の機能があります。このコードは出力します:
100ns
100ms
興味深いことに、ここのコードサンプルは、最も単純なコードを使用しており、Duration変換と同じ誤解を招くようなセマンティクスを持っています:https : //golang.org/pkg/time/#Duration
秒:= 10
fmt.Print(time.Duration(seconds)* time.Second)// 10秒を出力します
GoにDuration
型があることは素晴らしいことです。明示的に定義された単位があることで、実際の問題を防ぐことができます。
また、Goの厳密な型ルールのため、Durationを整数で乗算することはできません。一般的な型を乗算するには、キャストを使用する必要があります。
/*
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'
}
公式ドキュメントは、メソッド#1を使用して示しています。
整数の単位を期間に変換するには、以下を乗算します。
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
ただし、もちろん、期間に期間を乗算しても、期間は生成されません。これは、一見無意味です。その例として、5ミリ秒に5ミリ秒を掛けたものがが生成され6h56m40s
ます。5秒を2乗しようとすると、オーバーフローが発生します(定数を使用してコンパイルしてもコンパイルされません)。
ちなみに、ナノ秒単位のint64
表現はDuration
、「表現可能な最大期間を約290年に制限します」。これはDuration
、がのようint64
に、符号付きの値として扱われることを示しています。(1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
これは、実装方法とまったく同じです。
// 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
したがって、の基礎となる表現はDuration
でありint64
、の間int64
でキャストを実行しDuration
、賢明なNO-OP であることがわかっているため、型の混合に関する言語規則を満たすためにのみ必要であり、後続の乗算演算には影響しません。
純粋さの理由でキャストが気に入らない場合は、上で示したように関数呼び出しに埋め込んでください。
変数から時間への乗算。次のコードを使用して2番目
oneHr:=3600
addOneHrDuration :=time.Duration(oneHr)
addOneHrCurrTime := time.Now().Add(addOneHrDuration*time.Second)
time.Duration
変数を使用する良い方法ではありません。addOneHrDuration
時間の変数に名前を付けてtime.Duration
から、それを1時間ではなく3600 nsに設定します。Aはtime.Duration
たまたまナノ秒の基本単位を持っています。実際に1時間の期間を取得するには、次のようにしますconst oneHourDuration = 60 * time.Hour
(または3600 * time.Second
またはtime.Hour
)。
rand.Seed(time.Now().Unix())