菊花链输入,输出通道一起在golang

菊花链输入,输出通道一起在golang,go,goroutine,Go,Goroutine,我有以下接口和结构 type PiplineStep interface { Do(ctx context.Context, in <-chan Message) (<-chan Message, <-chan error, error) } type Pipline struct { Steps []core.PiplineStep } 现在,我尝试将接口菊花化,以创建如下所示的管道 for _, step := range p.Steps {

我有以下接口和结构

type PiplineStep interface {
    Do(ctx context.Context, in <-chan Message) (<-chan Message, <-chan error, error)
}

type Pipline struct {
    Steps []core.PiplineStep
}
现在,我尝试将接口菊花化,以创建如下所示的管道

    for _, step := range p.Steps {
        out, errc, err := step.Do(ctx, out)
        errcList = append(errcList, errc)

        if err != nil {
            errc <- err
            return
        }

        select {
        case outer <- msg:
        case <-ctx.Done():
            return
        }
    }
但是编译器说不,这可能吗

我得到了以下错误“out declared and not used”,我尝试了以下操作,但似乎所有步骤都收到了相同的chan

    for _, step := range p.Steps {
        var tmpOut <-chan core.Message
        tmpOut = out
        tmpOut, errcTmp, err := step.Do(ctx, tmpOut)
        errcList = append(errcList, errcTmp)

        if err != nil {
            errc <- err
            return
        }
        select {
        case out <- msg:
        case <-ctx.Done():
            return
        }
    }

如果要在每次迭代中重复使用通道变量,则必须在循环外部声明通道变量。为简洁起见,请忽略错误和上下文:

package main

import "fmt"

func main() {
    var pipeline Pipeline

    pipeline.Steps = append(pipeline.Steps,
            AddBang{},
            AddBang{},
            AddBang{},
    )

    src := make(chan Message)
    pipe := src

    for _, s := range pipeline.Steps {
            pipe = s.Do(pipe)
    }

    go func() {
            src <- "msg 1"
            src <- "msg 2"
            src <- "msg 3"
    }()

    fmt.Println(<-pipe)
    fmt.Println(<-pipe)
    fmt.Println(<-pipe)
}

type Message string

type Pipeline struct {
    Steps []PipelineStep
}

type PipelineStep interface {
    Do(in chan Message) chan Message
}

type AddBang struct{}

func (AddBang) Do(in chan Message) chan Message {
    out := make(chan Message)
    go func() {
            defer close(out)
            for m := range in {
                    out <- m + "!"
            }
    }()
    return out
}

在操场上试试:

编译器说“否”不是合适的问题描述。请展示完整、可编译和可运行的示例代码以及实际的编译器错误。缺乏幽默感?我得到一个编译时错误,必须使用声明的变量。如果您没有使用它,请将其替换为u。不,它没有使用,请学习Go变量范围规则。for loop语句中声明的变量的作用域为该语句。:=是变量声明和做作。这里有两个不同的out变量。您需要一个更完整的示例。你还没有展示你在哪里制作了一个频道,你说所有的步骤都收到了相同的chan-你制作了多个频道吗?如果将错误值放入错误通道,那么单独的错误值和错误通道有什么意义?也许这篇博文会给我们一些启示:有没有可能通过定向渠道来实现这一点?因此,我可以强制执行创建通道的步骤是唯一能够关闭通道或推入通道的步骤