2016-05-24 11 views
0

なぜチャネルで送信して実行をブロックしないのですか?このコンステレーションをMoneyDive()に信号を送信して実行を継続できるようにするにはどうすればいいですか?Golang:チャネルで送信できません

package main 

import (
    "fmt" 
) 

type Quack func(ch chan bool) 

type DagobertDuck struct { 
    quack Quack 
} 

func (self *DagobertDuck) MoneyDive() { 
    ch := make(chan bool) 
    self.quack(ch) 
    b := <-ch 
    if b { 
     fmt.Println("true") 
    } else { 
     fmt.Println("false") 
    } 
} 

func mockQuack(ch chan bool) { 
    fmt.Println("mockQuack start") 
    ch <- true 
    fmt.Println("mockQuack done") 
} 

func main() { 
    dd := DagobertDuck{quack: mockQuack} 
    dd.MoneyDive() 
} 

https://play.golang.org/p/1omlb7u6-A

答えて

3

あなたはバッファなしチャネルを持っており、あなたはそれから受信する準備ができている他のゴルーチンがある場合はブロックせずにバッファリングされていないチャンネルに値を送信することができますので。

ゴルーチンが1つしかないので、ブロックされます。ソリューションは単純です:新しいゴルーチンであなたのQuack.quack()方法を起動します。

go self.quack(ch) 

次に出力(Go Playground上でそれを試してみてください):

mockQuack start 
mockQuack done 
true 

は別のオプションは、新しいゴルーチンを起動するが、しないことですそれはそれから受信する準備ができて任意の受信機なしでいくつかの値を保持することができるようには、チャンネルをバッファリング:

ch := make(chan bool, 1) // buffered channel, buffer for 1 value 

これは、受信者が受け取る準備ができていない状態で、1つの値を「格納」できるチャネルを作成します。チャネルからの2回目の送信は、値が最初に受信されない限り(または受信者が値を受信する準備ができていない場合)ブロックされます。

Go Playgroundでこのバッファリングされたチャンネルのバージョンをお試しください。スペックから

関連セクション:通信が始まる前Send statements:

チャネルと値式の両方が評価されます。 送信が進むまでの通信ブロック。受信機が準備が整っていれば、バッファされていないチャンネルのセンドを進めることができます。バッファに空きがある場合、バッファされたチャネルでの送信を続行できます。閉じたチャネルでの送信は、run-time panicを引き起こすことによって進行します。 のnilチャネルブロックを永遠に送信します。

注:あなたがtruefalseを印刷受信した値に基づいて

。これはif書なしで、単一のラインで行うことができます:あなたもbローカル変数を取り除くことができます

fmt.Println(b) 

、とすぐに受信した値を出力します。また

fmt.Println(<-ch) 

私は仮定しますチャンネルを使用していましたので、あなたのケースではmockQuack()はチャンネルを使用せずにboolの値を返すだけでした。

+0

驚くばかりです。ありがとうございました。 –

関連する問題