在消费者可以随时取消的情况下,我正在通过读取器流式传输数据。通常,我只需要使用消费者调用reader.Close(),但是在这种情况下,阅读器需要为ReadCloser。 NopCloser是我目前知道的将Reader变成ReadCloser的唯一方法,但是关闭并不会做任何事情,因此,如果消费者离开了,我将无法通知生产者。是否有类似NopCloser的东西发出某种我可以在生产者端监听的信号?

最佳答案

据我了解,这可能是解决方案:https://play.golang.org/p/-d8eGFvwuYb

但是我认为这不是惯用语言,在我看来也像是一个XY问题...刚刚了解了这个词,顺便说一句,分享@Flimzy

package main

import (
    "bytes"
    "context"
    "fmt"
    "io"
    "time"
)

func main() {
    cs := goWrite()
    read(cs)
    time.Sleep(1)
}

func goWrite() CloseSignaler {
    buf := &bytes.Buffer{}
    cs := NewCloseSignaler(buf)
    go func() {
        defer fmt.Println("exit writer")
        for {
            select {
            case <-cs.ctx.Done():
                return
            default:
                buf.Write([]byte("A"))
            }
        }
    }()
    return cs
}

func read(rc io.ReadCloser) {
    p := make([]byte, 1)
    rc.Read(p)
    fmt.Printf("read %s\n", string(p))
    rc.Close()
}

// CloseSignaler

type CloseSignaler struct {
    io.Reader
    ctx    context.Context
    cancel func()
}

func NewCloseSignaler(r io.Reader) CloseSignaler {
    ctx, cancel := context.WithCancel(context.Background())
    return CloseSignaler{
        Reader: r,
        ctx:    ctx,
        cancel: cancel,
    }
}

func (cs CloseSignaler) Close() error {
    cs.cancel()
    return nil
}

10-05 19:00