在Golang中将一个函数类型转换为另一个函数

I have the following code:

package vault

type Client interface {
    GetHealth() error
}

func (c DefaultClient)  GetHealth () error {
    resp := &VaultHealthResponse{}
    err := c.get(resp, "/v1/sys/health")
    if err != nil {
        return err
    }
    return nil;
}

Now, I want to use this function as part of this struct:

type DependencyHealthFunction func() error

type Dependency struct {
    Name           string `json:"name"`
    Required       bool   `json:"required"`
    Healthy        bool   `json:"healthy"`
    Error          error  `json:"error,omitempty"`
    HealthFunction DependencyHealthFunction
}

Basically, set the value of HealthFunction to GetHealth. Now, when I do the following:

func (config *Config) GetDependencies() *health.Dependency {
    vaultDependency := health.Dependency{
        Name: "Vault",
        Required: true,
        Healthy: true,
        HealthFunction: vault.Client.GetHealth,
    }
    temp1 := &vaultDependency
    return temp1;
}

This gives me an error and it says cannot use vault.Client.GetHealth (type func(vault.Client) error) as type health.DependencyHealthFunction in field value. How can I do this?

Edit: How DependencyHealthFunction is used?

As its part of Dependency struct, it's simply used as following: d.HealthFunction() where d is a variable of type *Dependency.

This is abstract:

    HealthFunction: vault.Client.GetHealth,

If we were to call HealthFunction(), what code do you expect to run? vault.Client.GetHealth is just a promise that such a function exists; it isn't a function itself. Client is just an interface.

You need to create something that conforms to Client and pass its GetHealth. For example, if you had a existing DefaultClient such as:

defaultClient := DefaultClient{}

Then you could pass its function:

    HealthFunction: defaultClient.GetHealth,

Now when you later call HealthFunction() it will be the same as calling defaultClient.GetHealth().

https://play.golang.org/p/9Lw7uc0GaE

I believe the issue is related to understanding how interfaces are treated in Go.

An interface simply defines a method or set of methods that a particular type must satisfy to be considered as "implementing" the interface.

For example:

import "fmt"

type Greeter interface {
    SayHello() string
}

type EnglishGreeter struct{}

// Satisfaction of SayHello method
func (eg *EnglishGreeter) SayHello() string {
    return "Hello"
}

type SpanishGreeter struct{}

func (sg *SpanishGreeter) SayHello() string {
    return "Ola"
}

func GreetPerson(g Greeter) {
    fmt.Println(g.SayHello())
}

func main() {
    eg := &EnglishGreeter{}

    sg := &SpanishGreeter{}

    // greet person in english
    GreetPerson(eg)

    // greet person in spanish
    GreetPerson(sg)
}

You can add this behavior into a custom struct by simply having a Greeter field inside the struct. ie

type FrontEntrance struct {
    EntranceGreeter Greeter
}

fe := &FrontEntrance { EntranceGreeter: &EnglishGreeter{} }

// then call the SayHello() method like this
fe.EntranceGreeter.SayHello()

Interfaces in golang are useful for composing common expected behavior for types based on the methods that they satisfy.

Hope this helps.