簡體   English   中英

Golang:無法發送頻道

[英]Golang: cannot send on channel

為什么不在頻道上發送並阻止執行? 如何使這個星座工作,以便我可以向MoneyDive()發送信號並繼續執行?

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

因為你有一個無緩沖的通道,並且你只能在沒有阻塞的情況下在無緩沖的通道上發送一個值,如果有另一個goroutine可以從它接收的話。

由於你只有1個goroutine,它會被阻止。 解決方案很簡單:在新的goroutine中啟動Quack.quack()方法:

go self.quack(ch)

然后輸出(在Go Playground上試試):

mockQuack start
mockQuack done
true

另一個選擇是不啟動新的goroutine但是創建一個緩沖通道,因此它可以保存一些值而無需任何接收器准備接收它:

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

這創建了一個能夠“存儲”一個值而不需要任何接收器准備接收它的通道。 除非首先從它接收到值(或接收器准備從其接收值),否則通道上的第二次發送也將阻塞。

Go Playground上試試這個緩沖的頻道版本。

規范中的相關部分: 發送聲明:

在通信開始之前評估通道和值表達式。 通信阻塞,直到發送可以繼續。 如果接收器准備就緒,則可以繼續在無緩沖信道上發送。 如果緩沖區中有空間,則可以繼續緩沖通道上的發送。 關閉通道上的發送通過導致運行時恐慌而繼續 通道上發送永久阻止。

筆記:

根據收到的值,您打印truefalse 這可以使用單行完成,而不使用if語句:

fmt.Println(b)

你甚至可以擺脫b局部變量,並立即打印收到的值:

fmt.Println(<-ch)

另外我假設您使用了通道,因為您想要使用它們,但在您的情況下, mockQuack()可以簡單地返回bool值,而無需使用通道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM