Matt
Matt

Reputation: 22153

Is there any way to check if values are buffered in a Go chan?

How can I do something like the following?:

func foo(input <-chan char, output chan<- string) {
    var c char
    var ok bool
    for {
        if ThereAreValuesBufferedIn(input) {
            c, ok = <-input
        } else {
            output <- "update message"
            c, ok = <-input
        }
        DoSomethingWith(c, ok) 
    }
}

Basically, I want to check if there are buffered values in the chan so that if there aren't, I could send an update message before the thread is blocked.

Upvotes: 1

Views: 118

Answers (3)

zzzz
zzzz

Reputation: 91409

package main

func foo(input <-chan char, output chan<- string) {
        for {
                select {
                case c, ok := <-input:
                        if ok { // ThereAreValuesBufferedIn(input)
                                ... process c
                        } else { // input is closed
                                ... handle closed input
                        }
                default:
                        output <- "update message"
                        c, ok := <-input // will block
                        DoSomethingWith(c, ok)
                }

        }
}

EDIT: Fixed scoping bug.

Upvotes: 3

mna
mna

Reputation: 24003

Others have answered your question for what you wanted to do with your code (use a select), but for completeness' sake, and to answer the specific question asked by your question's title ("Is there any way to check if values are buffered in a Go chan?"), the len and cap built-in functions work as expected on buffered channels (len returns the number of buffered elements, cap returns the maximum capacity of the channel).

http://tip.golang.org/ref/spec#Length_and_capacity

Upvotes: 1

Daniel
Daniel

Reputation: 38849

Yes, this is what the select call allows you to do. It will enable you to check one or more channels for values ready to be read.

Upvotes: 3

Related Questions