在select语句中使用Reader接口时的约定

I've wrapped a queue to implement the Writer and Reader interfaces (for pushing and popping, respectively).

I need to continuously listen to the queue, and handle every message that comes through. This is simple when the queue is represented as a channel, but more difficult otherwise:

loop:
    for {
        var data []byte
        select {
            case <-done:
                break loop
            case _, err := queue.Read(data):
                fmt.Println(string(data))
        }
    }

What's the proper way to do this? Read here is blocking - it waits until the queue has a message.

Is there a better, more idiomatic way to achieve this?

It’s harder to take a synchronous API (like queue.Read as you described above) and make it asynchronous than it is to do the opposite.

The idea would be to create a new goroutine (using, for example go func() {...}) and have that goroutine execute the read and write the output to a channel.

Then the first goroutine would block on that channel and the one it’s already blocking on.

This has the potentially to leave orphaned resources for a little while if the read takes to long but if you have a synchronous API, it’s the best you can do.