Чтобы протестировать параллельные процедуры, я добавил строку в функцию, чтобы она возвращалась случайным образом (до одной секунды)
time.Sleep(rand.Int31n(1000) * time.Millisecond)
Однако, когда я скомпилировал, я получил эту ошибку
. \ crawler.go: 49: недопустимая операция: rand.Int31n (1000) * time.Millisecond (несовпадающие типы int32 и time.Duration)
Любые идеи? Как я могу умножить продолжительность?
rand.Seed(time.Now().Unix())
time.Sleep(time.Second * 2)
Duration
*Duration
=Duration
вместо исходного, что на самом деле имеет больше смысла:Duration
*int
=Duration
.int64(...) * Duration
имеет гораздо больше смысла, чем приведение кDuration
, что является лишь основным нарушением того, как должны работать юниты. К сожалению, это не работает. Вы действительно должны сделатьDuration * Duration
что ужасно.Вы должны привести его к правильному формату Playground.
Если вы проверите документацию для сна , вы увидите, что она требует
func Sleep(d Duration)
длительности в качестве параметра. Ваш rand.Int31n возвращаетсяint32
.Строка из примера работает (
time.Sleep(100 * time.Millisecond)
), потому что компилятор достаточно умен, чтобы понять, что здесь ваша постоянная 100 означает длительность. Но если вы передадите переменную, вы должны привести ее.источник
В Go вы можете умножать переменные одного типа, поэтому вам нужно, чтобы обе части выражения имели один и тот же тип.
Самое простое, что вы можете сделать, это привести целое число к длительности перед умножением, но это нарушит семантику юнитов. Что будет умножение длительности на длительность в единицах?
Я предпочел бы преобразовать время. Миллисекунды в int64, а затем умножить его на количество миллисекунд, а затем привести к времени. Продолжительность:
Таким образом, можно сказать, что любая часть выражения имеет значимое значение в соответствии с его типом.
int64(time.Millisecond)
Часть - это просто безразмерное значение - количество наименьших единиц времени в исходном значении.Если пройти немного более простой путь:
Левая часть умножения - нонсенс - значение типа «time.Duration», содержащее нечто, не относящееся к его типу:
И это не просто семантика, это фактическая функциональность, связанная с типами. Этот код печатает:
Интересно, что в данном примере кода используется самый простой код с той же вводящей в заблуждение семантикой преобразования Duration: https://golang.org/pkg/time/#Duration
источник
Приятно, что у Go есть
Duration
тип - наличие явно определенных единиц может предотвратить реальные проблемы.А из-за строгих правил типов Go вы не можете умножить Duration на целое число - вы должны использовать приведение для умножения общих типов.
Официальная документация демонстрирует использование метода # 1:
Но, конечно, умножение длительности на длительность не должно производить длительность - это бессмысленно. Например, 5 миллисекунд умножить на 5 миллисекунд
6h56m40s
. Попытка возвести в квадрат 5 секунд приводит к переполнению (и даже не скомпилируется, если сделано с константами).Кстати,
int64
представлениеDuration
в наносекундах «ограничивает наибольшую представляемую продолжительность примерно 290 годами» , и это указывает на тоDuration
, что , напримерint64
, обрабатывается как значение со знаком:(1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
и именно так оно и реализуется:Итак, поскольку мы знаем, что лежащим в основе представлением
Duration
является выполнениеint64
, выполняющее приведение междуint64
иDuration
разумным NO-OP, - требуется только для удовлетворения языковых правил о типах смешивания, и это не влияет на последующую операцию умножения.Если вам не нравится кастинг по соображениям чистоты, похороните его в вызове функции, как я показал выше.
источник
Для умножения переменной на время. Во-вторых, используя следующий код
источник
time.Duration
переменных Go . Вы называете свою переменнуюaddOneHrDuration
времени,time.Duration
но затем продолжаете устанавливать ее на 3600 нс, а не на один час. Аtime.Duration
бывает, что базовые единицы наносекунд. Чтобы фактически получить продолжительность в один час, вы можете сделать что-то вроде:const oneHourDuration = 60 * time.Hour
(или3600 * time.Second
илиtime.Hour
).