英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论