为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中将事物通道作为接口通道传递

在 Go 中将事物通道作为接口通道传递

Go
RISEBY 2021-07-25 20:27:26
我的程序有一个管道结构,我刚刚实现了一个缓存过滤器,如果已经处理过的数据版本在缓存中,它会直接将内容发送到输出。func Run(in chan downloader.ReadyDownload) chan CCFile {    out := make(chan CCFile)    processQueue := make(chan downloader.ReadyDownload)    go cache.BypassFilter(in, processQueue, out)        // writes the cached, already processed version to out if it exists        // otherwise redirects the input to processQueue    go process(processQueue, out)    return out}问题是我的程序有多个这样的地方,并且通过通道传递了多种结构(如本片段中的 ReadyDownload 和 CCFile)。他们都实现了这个接口type ProcessItem interface {    Source() string    Target() string    Key() string}所以我的 BypassFilter() 函数签名如下所示:func (c Cache) BypassFilter(in chan ProcessItem, process chan ProcessItem, bypass chan ProcessItem)但这会带来以下错误:cannot use in (type chan downloader.ReadyDownload) as type chan utils.ProcessItem in function argument尽管 ReadyDownload 确实实现了 ProcessItem。例如,这可以毫无问题地工作:foo := downloader.ReadyDownload{}var bar utils.ProcessItembar = foo因此,我对 Go 类型和接口的(但)非常有限的理解让我提出了这个问题:它们是某物和其他物的通道这一事实是否使类型不兼容?我该怎么做才能让它发挥作用?假设我有一个 ReadyDownloads 频道。是将数据转发到函数的唯一方法,该函数将接口的通道作为参数,以创建新的接口通道,将其传递给函数并从 ReadyDownloads 的通道读取内容并将它们馈送到另一个通道?
查看完整描述

2 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

将每个通道更改为struct通道可能在这里有效,但一般来说,您可能希望将您的struct类型视为用于处理的接口。幸运的是,go 给了我们很多解决方案。这是一个。


考虑这个非常简单的设置,我们希望使用Object结构类型作为多个接口:


// Get the objects

func ParseFile(fileName string, co chan Object) {

    for _, object := range DoStuff(fileName) {

        co <- object

    }

}


// Use some saving functionality that is defined elsewhere as:

func Archive(cs chan Saveable) {

    for saveable := range cs {

        saveable.Save()

    }

}


type Saveable interface {

    Save()

}


//Implement the interfaces...

func (*Object) Save() {

    fmt.Println("Naa, I'm lazy")

}


// Or some throwing functionality?

func ThrowOnTheWall(ct chan Throwable) {

    for throwable := range cs {

        throwable.Throw()

    }

}


//...


co := make(chan Object)

go ParseFile("file.xml", co)

Archive(co) // Will NOT work, co is of the wrong type.

在这里,在任何地方使用 somechan Object是不合适的,因为您可能想将一些与对象不同的东西扔到墙上(例如,type Defecation struct {...}您也将实现为 a Throwable。)。


您可以使用 go 例程在后台进行转换:


func ObjectToSaveable(from chan Object) chan Saveable {

    to := make(chan Saveable)

    go func() {

        for object := range from {

            to <- &object

        }

        close(to)

    }()

    return to

}

然后用它来封装初始通道:


co := make(chan Object)

go ParseFile("file.xml", co)

Archive(ObjectToSaveable(co))


查看完整回答
反对 回复 2021-08-02
  • 2 回答
  • 0 关注
  • 230 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信