猿问

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

我的程序有一个管道结构,我刚刚实现了一个缓存过滤器,如果已经处理过的数据版本在缓存中,它会直接将内容发送到输出。


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.ProcessItem

bar = foo

因此,我对 Go 类型和接口的(但)非常有限的理解让我提出了这个问题:它们是某物和其他物的通道这一事实是否使类型不兼容?我该怎么做才能让它发挥作用?假设我有一个 ReadyDownloads 频道。是将数据转发到函数的唯一方法,该函数将接口的通道作为参数,以创建新的接口通道,将其传递给函数并从 ReadyDownloads 的通道读取内容并将它们馈送到另一个通道?


RISEBY
浏览 231回答 2
2回答

梦里花落0921

将每个通道更改为struct通道可能在这里有效,但一般来说,您可能希望将您的struct类型视为用于处理的接口。幸运的是,go 给了我们很多解决方案。这是一个。考虑这个非常简单的设置,我们希望使用Object结构类型作为多个接口:// Get the objectsfunc ParseFile(fileName string, co chan Object) {&nbsp; &nbsp; for _, object := range DoStuff(fileName) {&nbsp; &nbsp; &nbsp; &nbsp; co <- object&nbsp; &nbsp; }}// Use some saving functionality that is defined elsewhere as:func Archive(cs chan Saveable) {&nbsp; &nbsp; for saveable := range cs {&nbsp; &nbsp; &nbsp; &nbsp; saveable.Save()&nbsp; &nbsp; }}type Saveable interface {&nbsp; &nbsp; Save()}//Implement the interfaces...func (*Object) Save() {&nbsp; &nbsp; fmt.Println("Naa, I'm lazy")}// Or some throwing functionality?func ThrowOnTheWall(ct chan Throwable) {&nbsp; &nbsp; for throwable := range cs {&nbsp; &nbsp; &nbsp; &nbsp; throwable.Throw()&nbsp; &nbsp; }}//...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 {&nbsp; &nbsp; to := make(chan Saveable)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for object := range from {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to <- &object&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; close(to)&nbsp; &nbsp; }()&nbsp; &nbsp; return to}然后用它来封装初始通道:co := make(chan Object)go ParseFile("file.xml", co)Archive(ObjectToSaveable(co))
随时随地看视频慕课网APP

相关分类

Go
我要回答