假设我有一个名为的接口Hello:
type Hello interface {
Hi() string
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个获取Hello和任何接口的函数,n并在Hello实现n接口的情况下执行某些操作,例如:
type Person interface {
Name() int
}
type Animal interface {
Leg() int
}
type hello struct{}
func (h hello) Hi() string {
return "hello!"
}
func (h hello) Leg() int {
return 4
}
func worker() {
h := hello{}
// Doesn't match
check(h,(Person)(nil))
// Matches
check(h,(Animal)(nil))
}
func check(h Hello, n interface{}) {
// of course this doesn't work, should I use reflection, if so how?
if _,ok := h.(n); ok {
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
如何实现该check功能?
使用反射 Type.Implements
func check(n interface{}) bool {
i := reflect.TypeOf(new(Hello)).Elem()
return reflect.TypeOf(n).Implements(i)
}
Run Code Online (Sandbox Code Playgroud)
如果要用作引用的接口是已知的,则可以在向函数传递new(Hello)或(*Hello)(nil)不传递额外参数的情况下对其进行实例化。
你不能使用,(Hello)(nil) 因为:
如果 i 是一个 nil 接口值,则
TypeOf返回nil。
否则,如果引用接口也是动态的,您可以将其作为参数传递。原理是一样的:
func main() {
fmt.Println(check(new(Hello), new(Person))) // false
}
func check(i interface{}, n interface{}) bool {
ti := reflect.TypeOf(i).Elem()
return reflect.TypeOf(n).Implements(ti)
}
Run Code Online (Sandbox Code Playgroud)
游乐场:https : //play.golang.org/p/GYDcxtIobKc
在 Go 1.18(2022 年初)中将泛型添加到语言中后,您将能够为此编写一个使用类型断言的泛型函数:
如果
T是接口类型,x.(T)则断言x实现接口的动态类型T。
它看起来像:
func check[T any](i T, n interface{}) bool {
_, ok := n.(T)
return ok
}
Run Code Online (Sandbox Code Playgroud)
Go2 游乐场:https ://go2goplay.golang.org/p/HIBn3IYW13W
| 归档时间: |
|
| 查看次数: |
91 次 |
| 最近记录: |