Types 什么是「;围棋;在go中检查自定义类型的方法?

Types 什么是「;围棋;在go中检查自定义类型的方法?,types,go,Types,Go,我试图在golang中测试对象的确切类型(无论是服装结构还是界面),并试图找出如何以一种不像廉价黑客那样真实的方式进行测试。(请注意,像字符串、整数、浮点、切片等内置类型不是我要问的) 假设我有一个实现Speak方法的动物界面: type Animal interface { Speak() string } 以及实现该接口的Dog结构: type Dog struct { } func (d Dog) Speak() string { return "Woof!" } 假

我试图在golang中测试对象的确切类型(无论是服装结构还是界面),并试图找出如何以一种不像廉价黑客那样真实的方式进行测试。(请注意,像字符串、整数、浮点、切片等内置类型不是我要问的)

假设我有一个实现Speak方法的动物界面:

type Animal interface {
    Speak() string
}
以及实现该接口的Dog结构:

type Dog struct {
}

func (d Dog) Speak() string {
    return "Woof!"
}
假设我有一些变量x,我如何检查它的结构类型并相应地执行操作

例如,我想要的是:

func isDog(thing Animal{}) bool {
    if reflect.TypeOf(thing) == packageName.Dog{
        return true
    }else{
        return false
    }
}
func isDog(thing Interface{}) bool {
    d := Dog{}
    if reflect.TypeOf(thing) == reflect.TypeOf(d){
        return true
    }else{
        return false
    }
}
func isDog(thing Interface{}) bool {
    d := Dog{}
    if reflect.TypeOf(thing) == packageName.Dog{
        return true
    }else if reflect.TypeOf(thing) == *packageName.Dog{
        return true
    }else{
        return false
    }
}
我想做的唯一解决办法并不是我真正想做的,但我想这是可行的。首先创建我要检查的类型的空结构,然后使用reflect包检查是否相等。比如:

func isDog(thing Animal{}) bool {
    if reflect.TypeOf(thing) == packageName.Dog{
        return true
    }else{
        return false
    }
}
func isDog(thing Interface{}) bool {
    d := Dog{}
    if reflect.TypeOf(thing) == reflect.TypeOf(d){
        return true
    }else{
        return false
    }
}
func isDog(thing Interface{}) bool {
    d := Dog{}
    if reflect.TypeOf(thing) == packageName.Dog{
        return true
    }else if reflect.TypeOf(thing) == *packageName.Dog{
        return true
    }else{
        return false
    }
}
我不喜欢的原因是,假设我有一个更大的代码,我最终需要一个switch语句。然后,我必须编写太多我觉得不必要的额外代码,比如,我需要创建大量的空结构类型,就像我有案例一样。这似乎没有必要,而且非常丑陋。这是唯一的办法吗?我还希望它足够灵活,可以检查指针。比如:

func isDog(thing Animal{}) bool {
    if reflect.TypeOf(thing) == packageName.Dog{
        return true
    }else{
        return false
    }
}
func isDog(thing Interface{}) bool {
    d := Dog{}
    if reflect.TypeOf(thing) == reflect.TypeOf(d){
        return true
    }else{
        return false
    }
}
func isDog(thing Interface{}) bool {
    d := Dog{}
    if reflect.TypeOf(thing) == packageName.Dog{
        return true
    }else if reflect.TypeOf(thing) == *packageName.Dog{
        return true
    }else{
        return false
    }
}

要确定接口变量的动态类型,可以使用。例如,
isDog
函数可以实现为:

func isDog(thing Animal) bool {
    _, isdog := thing.(packageName.Dog)
    _, isdogptr := thig.(*packageName.Dog)
    return isdog || isdogptr
}

要确定接口变量的动态类型,可以使用。例如,
isDog
函数可以实现为:

func isDog(thing Animal) bool {
    _, isdog := thing.(packageName.Dog)
    _, isdogptr := thig.(*packageName.Dog)
    return isdog || isdogptr
}

惯用的方法是直接使用类型断言,而不是类型断言

func isDog(animal Animal) bool {
    switch animal.(type) {
    case Dog:
    case *Dog:
    default:
        return false
    }
    return true
}

惯用的方法是直接使用类型断言,而不是类型断言

func isDog(animal Animal) bool {
    switch animal.(type) {
    case Dog:
    case *Dog:
    default:
        return false
    }
    return true
}

看起来和我想要的一模一样,但是。。。当我尝试时,代码抛出了一个我不理解的奇怪错误。它说
不可能的类型断言“github.com/pinocchio/farm/pkgName”。Dog不实现“github.com/pinocchio/farm/pkgName”。Animal
(Speak方法有指针接收器)。奇怪。。。我不明白这一点,这两个东西定义了完全相同的方法,并返回相同的类型,没有输入错误。如果你有一个像
func(d*Dog)Speak()string
这样的方法,它将只在
*Dog
的方法集中用于实现接口,而不是
Dog
。您无法获取指向存储在接口变量中的值的指针,因此无法使用该方法。@JamesHenstridge让我困惑的是,为什么它会崩溃?如果它不能转换成那种类型,为什么它不这么说而不是抛出一个错误呢?如果你有一个类型为
Dog
的变量
d
,并且调用
d.Speak()
,调用会自动转换成
(&d).Speak()
,因为该方法将指针作为它的接收器。问题是,您无法获取指向接口变量中存储的值的指针,因此该方法不被视为
Dog
方法集的一部分。由于这意味着
Dog
没有实现
Animal
接口,因此类型断言永远无法通过,因此编译器将其视为错误。这看起来与我想要的完全一样,但是。。。当我尝试时,代码抛出了一个我不理解的奇怪错误。它说
不可能的类型断言“github.com/pinocchio/farm/pkgName”。Dog不实现“github.com/pinocchio/farm/pkgName”。Animal
(Speak方法有指针接收器)。奇怪。。。我不明白这一点,这两个东西定义了完全相同的方法,并返回相同的类型,没有输入错误。如果你有一个像
func(d*Dog)Speak()string
这样的方法,它将只在
*Dog
的方法集中用于实现接口,而不是
Dog
。您无法获取指向存储在接口变量中的值的指针,因此无法使用该方法。@JamesHenstridge让我困惑的是,为什么它会崩溃?如果它不能转换成那种类型,为什么它不这么说而不是抛出一个错误呢?如果你有一个类型为
Dog
的变量
d
,并且调用
d.Speak()
,调用会自动转换成
(&d).Speak()
,因为该方法将指针作为它的接收器。问题是,您无法获取指向接口变量中存储的值的指针,因此该方法不被视为
Dog
方法集的一部分。因为这意味着
Dog
不实现
Animal
接口,类型断言无法通过,因此编译器将其视为错误。我认为此上下文中的空白标识符误用和
myVariable | | randomint
是严重的。我认为此上下文中的空白标识符误用和
myVariable | randomint
是严重的。