Кроме того, что icza сказал (qv), обратите внимание, что документация гласит:
Например, если программа еще не получила от tC:
if !t.Stop() {
<-t.C
}
Это нельзя сделать одновременно с другими приемами от канала таймера.
Можно утверждать, что это не лучший пример, поскольку предполагается, что таймер работал в то время, когда вы звонили t.Stop
. Но стоит упомянуть, что это плохая идея, если уже есть какая-то существующая программа, которая читает или может читать из t.C
.
(документация Reset
повторяет всеи в неправильном порядке, потому что Reset
сортирует до Stop
.)
По сути, вся область немного чревата . Нет хорошего общего ответа, потому что при возвращении с t.Stop
назад на ваш звонок есть как минимум три возможных ситуации:
- Никто не слушает канал, и таймер не установленканал сейчас. Это часто имеет место, если таймер уже был остановлен до вызова
t.Stop
. Если таймер уже был остановлен, t.Stop
всегда возвращает false. - Никто не слушает канал, и сейчас в канале есть отметка таймера. Это всегда тот случай, когда таймер работал, но
t.Stop
не смог остановить его срабатывание. В этом случае t.Stop
возвращает false. Это также тот случай, когда таймер работал , но срабатывал до , вы даже позвонили t.Stop
, и поэтому остановились самостоятельно, так что t.Stop
не смог его остановитьи вернул false. - Кто-то еще слушает канал.
В последней ситуации вы ничего не должны делать. В первой ситуации вы ничего не должны делать. Во второй ситуации вы, вероятно, хотите получать данные с канала, чтобы очистить его. Вот для чего их пример.
Можно утверждать, что:
if !t.Stop() {
select {
case <-t.C:
default:
}
}
- лучший пример. Он делает одну неблокирующую попытку, которая использует тик таймера, если он присутствует, и ничего не делает, если тика таймера нет. Это работает независимо от того, был ли таймер на самом деле, когда вы вызывали t.Stop
. В самом деле, это даже работает, если t.Stop
возвращает true
, хотя в этом случае t.Stop
остановило таймер, поэтому таймеру никогда не удавалось поставить отметку таймера в канале. (Таким образом, если в канале есть данные, они обязательно должны быть перенесены из предыдущего сбоя при очистке канала. Если таких ошибок нет, попытка получения, в свою очередь, была излишней.)
Но, если кто-то еще - кто-то другой горутин - читает или может читать канал, вам вообще не следует этого делать. Невозможно узнать, кто (вы или они) получит любой таймер таймера, который может быть в канале, несмотря на вызов Stop
.
Между тем, если вы не Если использовать таймер дальше, то относительно безопасно, просто оставить отметку таймера, если она есть, в канале. Он будет собираться мусором, когда сам канал будет собираться мусором. Конечно, имеет ли это смысл, зависит от того, что вы делаете с таймером, но в этих случаях достаточно просто вызвать t.Stop
и проигнорировать его возвращаемое значение.