golang中对time.NewTicker()返回的指针取值后调用Stop无法停止ticker

发布于 2022-09-07 08:50:43 字数 154 浏览 23 评论 0

图片描述

如图所示,代码不长,tickerTest1中对Ticker指针取值以后Stop没有反应,tickerTest2直接用返回的指针则没有任何问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若水微香 2022-09-14 08:50:43

翻了下 runtime 包,发现在 stop 的时候有这么一个判断 :

if i < 0 || i > last || tb.t[i] != t {
    return false
}

关键在于 tb.t[i] != t。如 @李毅 所说,如果使用 tick := *time.NewTicker(time.Second) 是复制了一份,则这个条件肯定为真,即不释放该计时器资源,相当于没有 stop。所以计时器没有停止。


大家都需要注意的是:不要对 Ticker.C 使用 range,因为在调用 Ticker.Stop 的时候并不会 close 该 channel,所以这里相当于一个死循环。

╰つ倒转 2022-09-14 08:50:43

v2 = *p1 将产生新的结构体 v2,它的值由 p1 指针所指的结构体复制而来。

因此,你在 tickerTest2() 中调用的 ticker.Stop() 并不是 time.NewTicker() 创建的那个,而是复制品。

举个例子参考下

package main

import (
    "testing"
)

func Test_dereference_pointer(t *testing.T) {
    type Foo struct {
        N int
    }

    p1 := &Foo{1}
    f2 := *p1 // 将 p1 克隆成新的结构体 f2,不是引用

    p1.N = 2
    f2.N = 3

    if p1.N != 2 || f2.N != 3 {
        t.Fatal("error")
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文