What is the "go" way to checking custom types in go?

huangapple go评论88阅读模式
英文:

What is the "go" way to checking custom types in go?

问题

我正在尝试测试一个对象的确切类型(无论是结构体还是接口)在golang中,我试图找出如何以一种不像廉价的黑客那样的方式来实现。(请注意,我不是在询问内置类型如字符串、整数、浮点数、切片等)。

假设我有一个实现了Speak方法的Animal接口:

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
    }
}

我想到的唯一解决方案并不是我真正想要的,但我想这样也可以。首先创建一个我想要检查的空结构体,然后使用reflect包来检查相等性。类似这样:

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

我不太喜欢这种方法的原因是,假设我有一个需要最终使用switch语句的较大代码。那么,我必须编写很多额外的代码,我觉得这是不必要的,比如,我需要创建与我有的case数目相同的空结构体类型。这似乎是不必要的,而且非常丑陋。这是唯一的方法吗?我还希望它足够灵活,可以检查指针。类似这样:

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
    }
}
英文:

I was trying to test the exact type of an object (either a costume struct or interface) in golang and was trying to figure out how to do it a way that does not real like a cheap hack. (Notice that built in types like strings, ints, floats, slices, etc are not what I am asking about).

Say that I have a Animal interface that implements a Speak method:

type Animal interface {
    Speak() string
}

and a Dog struct that implements that interface:

type Dog struct {
}

func (d Dog) Speak() string {
	return "Woof!"
}

say I have some variable x, how do I check what struct type it has and act accordingly?

For example I wanted something like:

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

The only solution that I thought of doing was not really what I wanted to do but I guess it works. First create an empty struct of the type I want to check and then use the reflect package to check for equality. Something like:

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

The reason I didn't really like that is, say I have a larger code that I need a switch statement eventually. Then, I have to write so much extra code that I feel is unnecessary, like, I need to create the number of many empty struct types as I have cases. It seems unnecessary and really ugly. Is that the only way to do it? I also wanted it to be flexible enough to me it check for pointers too. Something like:

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
	}
}

答案1

得分: 3

要确定接口变量的动态类型,可以使用type assertion的两个返回值形式。例如,你的isDog函数可以实现为:

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

To determine the dynamic type of an interface variable, you can use the two-return form of a type assertion. For example, your isDog function could be implemented as:

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

答案2

得分: 3

习惯的方式是使用类型开关而不是直接使用类型断言。

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

The idiomatic way is to use a type switch rather than type assertions directly.

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

huangapple
  • 本文由 发表于 2014年6月24日 13:50:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/24379192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定