Go non-blocking channel send, test-for-failure bef

2019-08-05 16:22发布

问题:

Is there a way to test for failure of a go channel send without actually attempting the send? The standard non-blocking send is like so:

msg := "hi"
select {
    case messages <- msg:
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
    }

The problem is that I need to have "msg" ready to send in order to test the channel.

I would like to test to see if a send will fail in a way that does not require having "msg" ready for sending.

回答1:

That would do no good in the general case, since you then have a race. After generating msg the channel may no longer be ready to send.

If you need this pattern, you either need a second channel for signaling,

select {
    case <-ready:
        msg := generateMsg()
        messages <- msg
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
}

or you can use a sync.Cond