2016-05-30 5 views
2

文字列値を受け取る単純なチャンネルを作成しています。しかし、明らかに私は各文字列の代わりに文字列内の各文字をプッシュしています。Goチャンネルは文字列全体の代わりに文字列を取ります。

私はおそらく非常に基本的なものを欠いているでしょう。私は間違って何をしていますか?

https://play.golang.org/p/-6E-f7ALbD

コード:

func doStuff(s string, ch chan string) { 
    ch <- s 
} 

func main() { 
    c := make(chan string) 
    loops := [5]int{1, 2, 3, 4, 5} 

    for i := 0; i < len(loops); i++ { 
     go doStuff("helloooo", c) 
    } 

    results := <-c 

    fmt.Println("channel size = ", len(results)) 

    // print the items in channel 
    for _, r := range results { 
     fmt.Println(string(r)) 
    } 
} 

答えて

4

あなたのコードが正しくチャネル上string秒を送信します。

func doStuff(s string, ch chan string){ 
    ch <- s 
} 

問題は、受信側である:

results := <- c 

fmt.Println("channel size = ", len(results)) 

// print the items in channel 
for _,r := range results { 
    fmt.Println(string(r)) 
} 

resultsは、の値(最初に送信された値)です。そして、あなたはこのstringの長さを印刷します。

次に、この文字列(results)をfor rangeでループし、runeをループして、それらを印刷します。

何がしたいことは、チャネルの値をループです:ランランタイムパニックになりますとき

// print the items in channel 
for s := range c { 
    fmt.Println(s) 
} 

この:あなたがチャネルを閉じることはありませんので

fatal error: all goroutines are asleep - deadlock! 

、およびfor rangeチャンネルが閉じられるまでチャンネル上で実行されます。だからいつかチャンネルを閉じる必要があります。

例えば者は、1秒待ってみましょう、それを閉じます。

go func() { 
    time.Sleep(time.Second) 
    close(c) 
}() 

この方法であなたのアプリケーションが実行され、1秒後に終了します。 Go Playgroundで試してみてください。

sync.WaitGroup:これはすべてのゴルーチンが作業を終えるまで(チャンネル上で値を送信するまで)待ってから、チャンネルを閉じます(不要な待機/遅延はありません)。

var wg = sync.WaitGroup{} 

func doStuff(s string, ch chan string) { 
    ch <- s 
    wg.Done() 
} 

// And in main(): 
for i := 0; i < len(loops); i++ { 
    wg.Add(1) 
    go doStuff("helloooo", c) 
} 
go func() { 
    wg.Wait() 
    close(c) 
}() 

Go Playgroundに、このいずれかを試してみてください。

注:

何かを5回繰り返すには、あなたがその醜いloops配列を必要としません。単純に実行します。

for i := 0; i < 5; i++ { 
    // Do something 
} 
+0

詳細情報をありがとうございました。 – Sudhakar

0

あなたの代わりに、文字列の文字をバック得ている理由あなたが変数にチャンネル結果を割り当て、あなたのケースであり、この変数に割り当てられたチャネルの結果を反復処理しているということです文字列を返します.Goでは、文字列をfor rangeループで繰り返してルーンを取得できます。

チャンネルの結果を繰り返し処理することなく、チャンネルを印刷するだけで済みます。

package main 

import (
    "fmt" 
) 

func doStuff(s string, ch chan string){ 
    ch <- s 
} 

func main() { 
    c := make(chan string) 
    loops := [5]int{1,2,3,4,5} 

    for i := 0; i < len(loops) ; i++ { 
     go doStuff("helloooo", c)  
    } 

    results := <- c 
    fmt.Println("channel size = ", len(results)) 
    fmt.Println(results) // will print helloooo 
} 
関連する問題