Приятно, что у 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 секунд приводит к переполнению (и даже не скомпилируется, если сделано с константами).
Кстати, 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, - требуется только для удовлетворения языковых правил о типах смешивания, и это не влияет на последующую операцию умножения.
Если вам не нравится кастинг по соображениям чистоты, похороните его в вызове функции, как я показал выше.
rand.Seed(time.Now().Unix())