为什么golang ticker.Stop()在tickerTest1中不起作用?

时间:2018-05-25 04:06:17

标签: go ticker

result of two testTicker

我知道Stop功能无法关闭频道。我只是对tickerTest1tickerTest2的两个不同结果感到困惑。

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 个答案:

答案 0 :(得分:1)

tickerTest2()按预期工作,所以让我们检查tickerTest1()

time.NewTicker()返回指针值,类型为*time.Ticker。这已经提示您应该将其用作:作为指针(并且不应该取消引用它)。

然而,您通过使用间接运算符取消引用它:

ticker := *time.NewTicker(time.Second)

通过解除引用它,ticker将是time.Ticker类型,非指针类型。它的值将是NewTicker()返回的指针指向的值的副本

仅此一项不会成为问题,因为只要您调用带有指针接收器的方法(例如Ticker.Stop()),Go就会自动获取ticker的地址。但是作为接收者传递的地址将是此ticker变量的地址,并且修改time.Ticker结构的任何方法只会修改此不同的副本,而不会修改time.Ticker值由NewTicker()函数的返回值指出。

因此,您实际上只停止存储在Ticker变量中的副本ticker,而不是Ticker返回的原始NewTicker()并且实际发送的副本{{1}}频道上的值。这仍然没有停止。