Почему gickang ticker.Stop() не работает в tickerTest1?
Я знаю Stop
Функция не может закрыть канал. Я просто запутался с двумя разными результатами tickerTest1
а также tickerTest2
,
package main
import (
"time"
"log"
)
func tickerTest1() {
ticker := *time.NewTicker(time.Second)
count := 0
go func() {
time.Sleep(3*time.Second)
ticker.Stop()
}()
for range ticker.C {
count ++
log.Println("tickerTest1:", count)
}
}
func tickerTest2() {
ticker := time.NewTicker(time.Second)
count := 0
go func() {
time.Sleep(3*time.Second)
ticker.Stop()
}()
for range ticker.C {
count ++
log.Println("tickerTest2:", count)
}
}
func main() {
go tickerTest1()
tickerTest2()
}
1 ответ
tickerTest2()
работает как положено, поэтому давайте рассмотрим tickerTest1()
,
time.NewTicker()
возвращает значение указателя, значение типа *time.Ticker
, Это уже намекает на то, что вы должны использовать его так: в качестве указателя (и не следует разыменовывать его).
Тем не менее, вы разыменовываете его, используя оператор косвенного обращения:
ticker := *time.NewTicker(time.Second)
Разыменовывая это, ticker
будет иметь тип time.Ticker
тип без указателя. И его значение будет копией значения, указанного указателем, который NewTicker()
возвращается.
Это само по себе не будет проблемой, потому что Go автоматически принимает адрес ticker
всякий раз, когда вы вызываете метод с указателем на него (например, Ticker.Stop()
). Но адрес, который передается как получатель, будет адресом этого ticker
переменная, и любой метод, который изменяет time.Ticker
struct будет изменять только эту отдельную копию, а не time.Ticker
значение, на которое указывает возвращаемое значение NewTicker()
функция.
Таким образом, в действительности, вы только останавливаете копию Ticker
хранится в ticker
переменная, а не оригинал Ticker
который был возвращен NewTicker()
и который на самом деле отправляет значения на канале. Это остается не остановленным.