Почему gickang ticker.Stop() не работает в tickerTest1?

результат двух testTicker

Я знаю 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() и который на самом деле отправляет значения на канале. Это остается не остановленным.

Другие вопросы по тегам