[英]How to know if a struct or pointer to struct implements an interface
我需要知道结构体或指向该结构体的指针是否实现了给定的接口。
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
func main() {
var a A = A{
i: 5,
}
Serialize(a)
Serialize(&a)
}
type Serializable interface {
//Serialize() string
//Deserialize(string)
Serializebyte() []byte
Deserializebyte(b []byte) (bytesRead int)
}
type A struct {
i int
}
func (*A) Serializebyte() []byte {
return []byte{0x00}
}
func (*A) Deserializebyte(b []byte) (bytesRead int) {
return 0
}
func Serialize(objInt interface{}) []byte {
// this doesn't work
switch v := (objInt).(type) {
case Serializable:
fmt.Printf("I'm Serializable\n")
return v.Serializebyte()
}
fmt.Printf("I'm not Serializable\n")
return []byte{0x00}
}
// this other way also dont work
func Serialize2(objInt interface{}) []byte {
// this doesn't work
_, isSerializable := objInt.(Serializable)
if isSerializable{
fmt.Printf("I'm Serializable\n")
return objInt.(Serializable).Serializebyte()
}
fmt.Printf("I'm not Serializable\n")
return []byte{0x00}
}
// Stdout:
// I'm not Serializable
// I'm Serializable
编辑:您可以运行上面的代码来了解我的意思。
因为(*A)
实现了Serializable
而不是A
,上面的断言没有通过,但我想知道是(*A)
实现了Serializable
还是A
实现了它。
为什么我想要那个? 因为如果我能做到这一点,程序员就不需要知道Serializable
是如何工作的。 如果不是,程序员应该总是需要将指针传递给Serializable
并在结构指针中实现Serializable
而不是结构本身。
当用户给你T
时,使用*T
通常是一个坏主意。 *T
上的所有修改都不会对用户数据生效。
但如果这是你真正想要的,你可以使用反射。
func testFool(a interface{}) bool {
if _, ok := a.(Fool); ok {
return true
}
t := reflect.PtrTo(reflect.TypeOf(a))
FoolType := reflect.TypeOf((*Fool)(nil)).Elem()
return t.Implements(FoolType)
}
游乐场: https : //play.golang.org/p/rqJe5_KAP6e
编辑:如果您需要通过指针接收器使用该方法,您可以使用reflect.Value
而不是reflect.Type
。 但是,它会生成参数的额外副本。
func testFool(a interface{}) bool {
if _, ok := a.(Fool); ok {
return true
}
t := reflect.TypeOf(a)
v := reflect.New(t)
v.Elem().Set(reflect.ValueOf(a))
ptrA := v.Interface()
if foo, ok := ptrA.(Fool); ok {
foo.Foo()
return true
}
return false
}
使用refelct.NewAt
和·reflect.Value.InterfaceData` 编写免拷贝版本代码是可以破解的。 但是非常不推荐:它很可能会破坏您未来的代码并且难以维护; 它在引擎盖下使用不安全的包。
func Serialize(objInt interface{}) []byte {
switch v := objInt.(type) {
case Serializable:
return v.Serializebyte()
}
// do stuf on object that do not implement Serializebyte
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.