我在main()
中有以下代码:
msgs, err := ch.Consume(
q.Name, // queue
//..
)
cache := ttlru.New(100, ttlru.WithTTL(5 * time.Minute)) //Cache type
//log.Println(reflect.TypeOf(msgs)) 'chan amqp.Delivery'
go func() {
//here I use `cache` and `msgs` as closures. And it works fine.
}
我决定创建单独的函数而不是匿名函数。
我将其声明为func hitCache(cache *ttlru.Cache, msgs *chan amqp.Delivery) {
我得到编译异常:
./go_server.go:61: cannot use cache (type ttlru.Cache) as type *ttlru.Cache in argument to hitCache:
*ttlru.Cache is pointer to interface, not interface
./go_server.go:61: cannot use msgs (type <-chan amqp.Delivery) as type *chan amqp.Delivery in argument to hitCache
问题:我应该如何将msg
和cache
传递给新功能?
答案 0 :(得分:2)
好吧,如果接收变量或函数参数需要一个值
类型为*T
- 即“指向T
的指针”,
并且你有一个T
类型的变量,以获得指向它的指针,
你必须获取该变量的地址。
那是因为“指针”是一个持有地址的值。
Go中的地址获取操作符为&
,因此您需要类似
hitCache(&cache, &msgs)
但请注意某些类型具有所谓的“引用语义”。 也就是说,它们的值将引用保留为某些“隐藏”数据结构。 这意味着当您复制这些值时,您将复制所有引用相同数据结构的引用。
在Go中,内置类型的地图,切片和通道具有引用语义, 因此你几乎不需要传递指向这些类型的值的指针(好吧,有时它可能有用但现在不是。)
接口也可以被认为具有引用语义(现在不要讨论这个),因为任何接口类型的每个值都包含两个指针。
因此,在您的情况下,最好不要将函数的形式参数声明为指针 - 将它们声明为“普通”类型并使用它完成。
总而言之,你一定要在Go上完成一些基本资源,这些资源可以更详细,更广泛地解释这些基本问题。
答案 1 :(得分:1)
你在函数签名中使用了指针但没有传递指针 - 这很好;如评论中所述,没有理由使用指针作为接口或通道值。只需将函数签名更改为:
hitCache(cache ttlru.Cache, msgs chan amqp.Delivery)
它应该可以正常工作。
答案 2 :(得分:0)
接口指针几乎从未使用过。您可以简化事物并使用pass by value的接口。