2014-01-09 2 views
5
package main 

import (
    "fmt" 
    "time" 
) 

func fib() chan int { 
    c := make(chan int) 

    go func() { 
     c <- 0 
     c <- 1 

     n, m := 0, 1 
     for { 
      temp := n + m 
      n = m 
      m = temp 
      c <- m // This results in panic, when the channel is closed 
     } 
    }() 

    return c 
} 

func main() { 
    start := time.Now() 
    var lastFib int 
    c := fib() 

    for i := 0; i != 1000000; i++ { 
     lastFib = <-c 
    } 

    close(c) 
    fmt.Println(lastFib) 
    fmt.Println(time.Now().Sub(start)) 
} 

Auf die idiomatische Art und Weise, wie würde man die Panik in der Goroutine vermeiden, wenn der Kanal geschlossen ist? Oder sollte ich überhaupt vermeiden, close zu verwenden?Panik vermeiden, wenn versucht wird, einen Wert in einen geschlossenen Kanal einzutragen

Ich bin nicht auf alternative Methoden (wie Verschlüsse), um das gleiche zu erreichen, nur versuchen, ein besseres Verständnis der Kanäle zu bekommen.

Antwort

7

Close ist ein guter Weg für das Goroutine Senden in einen Kanal, um der Empfangsseite zu signalisieren, dass Sie mit diesem Kanal fertig sind. Andersherum (dein Problem) ist IMHO rückgängig, zumindest direkt. Du könntest einen anderen Kanal hinzufügen, der deiner fibonacci-generierenden Goroutine das Ende der Pflicht signalisiert. Hier

1

ist eine modifizierte Version von Ihrem Beispiel der Kanäle in einer erlaubt (wenn auch nicht unbedingt sinnvoll) Art und Weise verwendet:

package main 

import (
    "fmt" 
    "time" 
) 

func fib(c chan int) { 
    c <- 0 
    c <- 1 

    n, m := 0, 1 
    for { 
     temp := n + m 
     n = m 
     m = temp 
     c <- m 
     if m > 100000000 { 
      close(c) 
      break 
     } 
    } 
} 

func main() { 
    start := time.Now() 
    lastFib, newFib := 0, 0 
    ok := true 
    c := make(chan int) 
    go fib(c) 

    for { 
     newFib, ok = <-c 
     if !ok { 
      fmt.Println(lastFib) 
      break 
     } 
     lastFib = newFib 
    } 

    fmt.Println(time.Now().Sub(start)) 
} 
Verwandte Themen