嗨,我正在尝试检索一个结构的功能/方法,但是我正在使用一个接口作为参数,并且正在使用该接口尝试访问该结构的功能。在下面演示我想要的是我的代码
// 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
}
答案 0 :(得分:18)
要直接回答该问题,即将interface
转换为具体类型,请执行以下操作:
v = i.(T)
其中i
是接口,T
是具体类型。如果基础类型不是T,它将感到恐慌。要进行安全类型转换,请使用:
v, ok = i.(T)
,并且如果基础类型不是T
,则将ok设置为false
,否则设置为ture
。请注意,T
也可以是接口类型,如果是,则代码会将i
强制转换为新接口,而不是具体类型。
请注意,投射接口可能是不良设计的象征。就像在代码中一样,您应该问自己:自定义界面Connection
仅需要GetClient
还是总是需要GetValue
?您的GetRedisValue
函数需要一个Connection
还是总是需要一个具体的结构?
相应地更改代码。
答案 1 :(得分:1)
您的Connection
界面:
type Connection interface {
GetClient() (*redis.Client, error)
}
只说有一个GetClient
方法,没有说支持GetValue
。
如果您要像这样在GetValue
上致电Connection
:
func GetRedisValue(c Connection, key string) (string, error) {
value, err := c.GetValue(key)
return value, err
}
然后您应该在界面中包含GetValue
:
type Connection interface {
GetClient() (*redis.Client, error)
GetValue(string) (string, error) // <-------------------
}
现在,您说的是所有Connection
都将支持您要使用的GetValue
方法。