在Go中将函数转换为另一种类型(函数转换)

I've recently learnt that in the net/http package, there's a pattern of usage that keeps confusing me most. It is function type conversion. It is like this:

(function a) ->convert to-> (type t)
(type t) ->implentments-> (interface i)

So, if there's a function that takes interface i as its parameter, it will invoke the function a, this is the way net/http implements it.

But when I write my own code, I've had many misunderstandings on this pattern. My code goes like this:

package main

import (
    "fmt"
)

type eat interface {
    eat()
}
type aaa func()

func (op *aaa) eat() {//pointer receiver not right
    fmt.Println("dog eat feels good")
}

///////////////////////////////////////////////
func dog() {
    fmt.Println("I'm a dog")
}
///////////////////////////////////////////////

func feelsGood(a eat) {
    a.eat()
}

func main() {
    b := aaa(dog)
    feelsGood(b)
}

//error:aaa does not implement eat (eat method has pointer receiver)

Type aaa has method eat, the same function name and parameter signature, which conforms to the rule of interface eat, but why does it give that error? Does the receiver matter?

Another question is with only a function and type, excluding an interface, the code goes like this:

package main

import (
    "fmt"
)

type aaa func()

func (op *aaa) eat() {
    op()
}

///////////////////////////////////////////////
func dog() {
    fmt.Println("I'm a dog")
}
///////////////////////////////////////////////

func main() {
    obj:=aaa(dog)
    obj.eat()
}
//error:cannot call non-function op (type *aaa)

First, is op an anonymous function, regardless of the error?

Second, it works well after I remove the asterisk, but why? op is instance of type aaa, receiver is op, does op stand for function dog()? The http package uses f(w,r) the same way, but it is a little bit of hard to understand. Is op a type, or an instance, or an anonymous function?

It seems like my comprehension of function converting is not right, but I've also checked many posts on Google, and none of them can teach me how to think of it and use it correctly.Thank you!

For the first part of your question: See http://golang.org/doc/faq#different_method_sets which exmplains everything better than I could. You may even search stackoverflow and the golang-nuts mailing list for this question as this comes up very often.

The second is just the same IMHO: aaa doesn't have an eat-method (only *aaa has).

Question 1:

In Go, for a type T (like aaa in your case), T and *T have different method sets.

So, a value of type T can only access method:

func(t T)Foo() { ... }

While a value of type *T can access both methods:

func(t T)Foo() { ... }
func(t *T)Bar() { ... }

In your case, you have two options. Either you declare the eat method for aaa instead od *aaa:

func (op aaa) eat() {
    op()
}

Or you pass the pointer to b to feelsGood:

feelsGood(&b)

Question 2:

Yes, this question is related to the first. But in this case you can access the method because obj.eat() will be short for (&obj).eat().

Your problem here is that you cannot call a function on the function pointer (op *aaa). Your options are to either create the method for aaa instead of *aaa:

func (op aaa) eat() {
    op()
}

Or to call the op function on the value and not the pointer:

func (op *aaa) eat() {
    (*op)()
}