指针发送给函数

I have following code in 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.
    }

I decided to create separate function for instead of anonymous.

I declared it as func hitCache(cache *ttlru.Cache, msgs *chan amqp.Delivery) {

I get compile exception:

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

Question: How should I pass msg and cache into the new function?

Well, if the receiving variable or a function parameter expects a value of type *T — that is, "a pointer to T", and you have a variable of type T, to get a pointer to it, you have to get the address of that variable. That's because "a pointer" is a value holding an address.

The address-taking operator in Go is &, so you need something like

hitCache(&cache, &msgs)

But note that some types have so-called "reference semantics". That is, values of them keep references to some "hidden" data structure. That means when you copy such values, you're copying references which all reference the same data structure.

In Go, the built-in types maps, slices and channels have reference semantics, and hence you almost never need to pass around pointers to the values of such types (well, sometimes it can be useful but not now).

Interfaces can be thought of to have reference semantics, too (let's not for now digress into discussing this) because each value of any interface type contains two pointers.

So, in your case it's better to merely not declare the formal parameters of your function as pointers — declare them as "plain" types and be done with it.


All in all, you should definitely complete some basic resource on Go which explains these basic matters in more detail and more extensively.

You're using pointers in the function signature but not passing pointers - which is fine; as noted in the comments, there is no reason to use pointers for interface or channel values. Just change the function signature to:

hitCache(cache ttlru.Cache, msgs chan amqp.Delivery)

And it should work fine.

Pointers to interfaces are nearly never used. You may simplify things and use interfaces of pass by value.