【发布时间】:2014-05-02 15:38:45
【问题描述】:
我的程序有一个管道结构,我刚刚实现了一个缓存过滤器,如果已经处理的数据版本在缓存中,它会直接将内容发送到输出。
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
}
问题是我的程序有多个这样的地方,并且许多类型的结构(如本 sn-p 中的 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 的通道中读取内容并将它们提供给另一个频道?
【问题讨论】:
-
顺便说一句。问题本身最简单的解决方案可能就是创建 ProcessItems 的所有通道通道,然后在需要时将事物类型断言回它们自己的类型。但我想问这个问题,因为我认为从长远来看,了解 Go 的方式和原因会更有益。
标签: generics interface go channel