golang中的隐式接口转换
Implicit interface conversion in golang
这是我想展示的想法的一个例子。
package main
import "fmt"
// interface declaration
//
type A interface {
AAA() string
}
type B interface{
Get() A
}
// implementation
//
type CA struct {}
// implementation of A.AAA
func (ca *CA) AAA() string {
return "it's CA"
}
type C struct {}
// implementation of B.Get, except for returning a 'struct' instead of an 'interface'
func (c *C) Get() *CA {
return &CA{}
}
func main() {
var c interface{} = &C{}
d := c.(B)
fmt.Println(d.Get().AAA())
fmt.Println("Hello, playground")
}
在这个例子中
- 接口
B
有方法 Get
到 return 接口 A
- struct
C
有一个成员函数 Get
到 return 一个指向 struct CA
的指针,它实现了接口 A
结果是 Go 无法从结构 C
中推导出接口 B
,即使他们的 Get
方法只是在 returning 类型上不同,它是可转换的.
之所以提这个问题是因为interface A,B和struct C,CA在不同的包里,我只能:
- 将
C
的Get方法细化为func Get() A,引入包间的依赖
- 将接口
B
和结构 C
的 Get
方法都优化为 func Get() 接口{}
我想避免包之间的依赖,尽量不依赖接口{},谁能给我一些提示吗? Go 的最佳实践是什么?
您当前的 *C
类型 没有 实现接口 B
,因此您不能将 *C
的值分配给B
类型的变量也不能从持有 *C
.
类型值的对象中 "type assert" 值 B
您可以执行以下操作。由于您已经在使用结构文字 (&C{}
),因此您可以将 c
声明为 *C
类型,您可以调用它的 Get()
方法,并且您可以将 C.Get()
的 return 值转换为 A
(因为 return 值确实实现了 A
):
var c *C = &C{}
var a A = c.Get() // This is ok, implicit interface value creation (of type A)
fmt.Println(a.AAA())
// Or without the intermediate "a", you can simply call:
fmt.Println(c.Get().AAA())
输出:
it's CA
it's CA
或重构:
问题是您有一个要实现的接口 (B
),它有一个方法 return 是另一个接口 (A
)。要实现这个 B
接口,你必须依赖定义 A
的包,你无法避免这一点。并且您必须将 C.Get()
声明为 return A
(而不是具体的结构类型)。
您可以将 A
移动到第三个包,然后定义 C
的包将只依赖于这个第三个包,而不依赖于定义 [=13] 的包=](但仍将隐式实现接口类型B
)。
这是我想展示的想法的一个例子。
package main
import "fmt"
// interface declaration
//
type A interface {
AAA() string
}
type B interface{
Get() A
}
// implementation
//
type CA struct {}
// implementation of A.AAA
func (ca *CA) AAA() string {
return "it's CA"
}
type C struct {}
// implementation of B.Get, except for returning a 'struct' instead of an 'interface'
func (c *C) Get() *CA {
return &CA{}
}
func main() {
var c interface{} = &C{}
d := c.(B)
fmt.Println(d.Get().AAA())
fmt.Println("Hello, playground")
}
在这个例子中
- 接口
B
有方法Get
到 return 接口A
- struct
C
有一个成员函数Get
到 return 一个指向 structCA
的指针,它实现了接口A
结果是 Go 无法从结构 C
中推导出接口 B
,即使他们的 Get
方法只是在 returning 类型上不同,它是可转换的.
之所以提这个问题是因为interface A,B和struct C,CA在不同的包里,我只能:
- 将
C
的Get方法细化为func Get() A,引入包间的依赖 - 将接口
B
和结构C
的Get
方法都优化为 func Get() 接口{}
我想避免包之间的依赖,尽量不依赖接口{},谁能给我一些提示吗? Go 的最佳实践是什么?
您当前的 *C
类型 没有 实现接口 B
,因此您不能将 *C
的值分配给B
类型的变量也不能从持有 *C
.
B
您可以执行以下操作。由于您已经在使用结构文字 (&C{}
),因此您可以将 c
声明为 *C
类型,您可以调用它的 Get()
方法,并且您可以将 C.Get()
的 return 值转换为 A
(因为 return 值确实实现了 A
):
var c *C = &C{}
var a A = c.Get() // This is ok, implicit interface value creation (of type A)
fmt.Println(a.AAA())
// Or without the intermediate "a", you can simply call:
fmt.Println(c.Get().AAA())
输出:
it's CA
it's CA
或重构:
问题是您有一个要实现的接口 (B
),它有一个方法 return 是另一个接口 (A
)。要实现这个 B
接口,你必须依赖定义 A
的包,你无法避免这一点。并且您必须将 C.Get()
声明为 return A
(而不是具体的结构类型)。
您可以将 A
移动到第三个包,然后定义 C
的包将只依赖于这个第三个包,而不依赖于定义 [=13] 的包=](但仍将隐式实现接口类型B
)。