bugfix> go > 投稿

私は Stop を知っています関数はチャネルを閉じることができません。 tickerTest1 の2つの異なる結果と混同されています。および 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 を変更するメソッド  構造体はこの個別のコピーのみを変更し、 time.Ticker は変更しません   NewTicker() の戻り値が指す値  関数。

    したがって、実際には、コピー Ticker のみを停止します   ticker に保存  元の Ticker ではなく変数   NewTicker() によって返された  実際にチャネルで値を送信しています。それは止まらないままです。

あなたの答え