Golang Cast接口到struct

Mad*_*ing 6 go redis

嗨,我正在尝试检索一个结构的函数/方法,但我使用接口作为参数,并使用此接口我试图访问结构的功能.为了证明我想要的是下面的代码

// Here I'm trying to use "GetValue" a function of RedisConnection but since "c" is an interface it doesn't know that I'm trying to access the RedisConnection function. How Do I fix this?
func GetRedisValue(c Connection, key string) (string, error) {
    value, err := c.GetValue(key)

    return value, err
}

// Connection ...
type Connection interface {
    GetClient() (*redis.Client, error)
}

// RedisConnection ...
type RedisConnection struct {}

// NewRedisConnection ...
func NewRedisConnection() Connection {
    return RedisConnection{}
}

// GetClient ...
func (r RedisConnection) GetClient() (*redis.Client, error) {
    redisHost := "localhost"
    redisPort := "6379"

    if os.Getenv("REDIS_HOST") != "" {
        redisHost = os.Getenv("REDIS_HOST")
    }

    if os.Getenv("REDIS_PORT") != "" {
        redisPort = os.Getenv("REDIS_PORT")
    }

    client := redis.NewClient(&redis.Options{
        Addr:     redisHost + ":" + redisPort,
        Password: "", // no password set
        DB:       0,  // use default DB
    })

    return client, nil
}

// GetValue ...
func (r RedisConnection) GetValue(key string) (string, error) {
    client, e := r.GetClient()
    result, err := client.Ping().Result()
    return result, nil
}
Run Code Online (Sandbox Code Playgroud)

lea*_*bop 27

要直接回答这个问题,即将其interface转换为具体类型,您可以:

v = i.(T)
Run Code Online (Sandbox Code Playgroud)

i接口在哪里,T是具体类型.如果基础类型不是T,它将会出现恐慌.要进行安全演员,您可以使用:

v, ok = i.(T)
Run Code Online (Sandbox Code Playgroud)

如果底层类型不是T,则设置为ok false,否则true.请注意,T它也可以是接口类型,如果是,则代码i转换为新接口而不是具体类型.

请注意,构建界面可能是糟糕设计的象征.在您的代码中,您应该问问自己,您的自定义界面是否Connection仅需要GetClient或者是否始终需要GetValue?你的GetRedisValue函数需要一个Connection或者它总是需要一个具体的结构吗?

相应地更改您的代码.


mu *_*ort 13

您的Connection界面:

type Connection interface {
    GetClient() (*redis.Client, error)
}
Run Code Online (Sandbox Code Playgroud)

只说有GetClient方法,没说支持GetValue

如果你想这样调用GetValueConnection

func GetRedisValue(c Connection, key string) (string, error) {
    value, err := c.GetValue(key)
    return value, err
}
Run Code Online (Sandbox Code Playgroud)

GetValue那么你应该在界面中包含:

type Connection interface {
    GetClient() (*redis.Client, error)
    GetValue(string) (string, error) // <-------------------
}
Run Code Online (Sandbox Code Playgroud)

现在您说所有Connections 将支持GetValue您要使用的方法。