2016-01-27 35 views
5

Perché questo codice Golang non viene selezionato tra più tempi. Dopo che i canali funzionano?Perché questo codice Golang non viene selezionato tra più tempi. Dopo che i canali funzionano?

Vedere il codice di seguito. Il messaggio "timeout" non viene mai emesso. Perché?

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    count := 0 
    for { 
     select { 
     case <-time.After(1 * time.Second): 
      count++ 
      fmt.Printf("tick %d\n", count) 
      if count >= 5 { 
       fmt.Printf("ugh\n") 
       return 
      } 
     case <-time.After(3 * time.Second): 
      fmt.Printf("timeout\n") 
      return 
     } 
    } 
} 

eseguire sul Parco giochi: http://play.golang.org/p/1gku-CWVAh

uscita:

tick 1 
tick 2 
tick 3 
tick 4 
tick 5 
ugh 
+0

Eventuali duplicati di [timeout golang non viene eseguito con canali] (http://stackoverflow.com/questions/34894927/golang-timeouts-is-not-executed-with-channels) – icza

risposta

10

Perché time.After è una funzione, così ad ogni iterazione restituisce un nuovo canale. Se si desidera che questo canale per essere lo stesso per tutte le iterazioni, si dovrebbe salvarlo prima del ciclo:

timeout := time.After(3 * time.Second) 
for { 
    select { 
    //... 
    case <-timeout: 
     fmt.Printf("timeout\n") 
     return 
    } 
} 

Playground: http://play.golang.org/p/muWLgTxpNf.

+0

Grande! Stavo creando più canali! Grazie! – Everton

3

Anche @Ainar-G ha già fornito la risposta, un'altra possibilità è utilizzare time.Tick(1e9) per generare un segno di spunta ogni secondo e quindi ascoltare il canale timeAfter dopo il periodo specificato.

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    count := 0 
    timeTick := time.Tick(1 * time.Second) 
    timeAfter := time.After(5 * time.Second) 

    for { 
     select { 
     case <-timeTick: 
      count++ 
      fmt.Printf("tick %d\n", count) 
      if count >= 5 { 
       fmt.Printf("ugh\n") 
       return 
      } 
     case <-timeAfter: 
      fmt.Printf("timeout\n") 
      return 
     } 
    } 
}