指针发送功能

时间:2017-11-16 13:53:00

标签: pointers go

我在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

问题:我应该如何将msgcache传递给新功能?

3 个答案:

答案 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的接口。