英文:
Is it possible to store a Go type
问题
我有一些接口和任意实现这些接口的结构体。我想要存储一个类型的数组,并能够遍历它们以查看哪些接口被实现了。是否可以存储这样的类型?我花了一些时间研究了反射包,但没有找到我想要的东西,如果这不是最佳实践的话,我可以理解。我想要做类似于这样的事情...而不是使用一个庞大的类型开关、fallthrough或者if..if...if。
type InterOne interface {
InterOneMethod() string
}
var interfaceMap = map[string]interface{}{
"One": InterOne,
...
}
func doesHandle(any interface{}) []string {
var handles []string
for k, v := range interfaceMap {
if _, ok := any.(v); ok {
handles = append(handles, k)
}
}
return handles
}
编辑:被标记为正确答案的回答在技术上是正确的。但是由于关于方法调用和反射的过度使用的评论,我发现这种方法是不好的。相反,我使用了类型开关来检查单个接口,因为类型开关不支持fallthrough,并且使用了大量的if..if...if..来进行类型断言以进行适当的调用。
英文:
I've got a handful of interfaces, and n number of structs that arbitrarily implement these interfaces. I'd like to keep an array of types and be able to run a loop over them to see which ones are implemented. Is it possible to store a type like this? I spent a little bit of time with the reflect package, but couldn't really find what I was looking for, I understand if maybe this isn't best practice. Trying to do something similar to this.. without a giant type switch, fallthrough, or if.. if... if.
type InterOne interface {
InterOneMethod() string
}
var interfaceMap = map[string]type {
"One": InterOne,
...
}
func doesHandle(any interface{}) []string {
var handles []string
for k, v := range interfaceMap {
if _, ok := any.(v); ok {
handles = append(handles, k)
}
}
return handles
}
EDIT: The answer marked as correct is technically right. I found that due to the comment about the method calling & the overuse of reflection, that this approach was a bad idea. Instead I went with a type switch to check for a single interface because fallthrough is not supported on type switch, and a large if.. if.. if.. with type assertions to be able to make the appropriate calls.
答案1
得分: 2
你可以使用反射(reflect)包,注意获取接口类型的唯一方法是使用 reflect.TypeOf((*INTERFACE)(nil)).Elem()
,下面是一个可行的示例:
var interfaceMap = map[string]reflect.Type{
"One": reflect.TypeOf((*InterOne)(nil)).Elem(),
// ...
}
func doesHandle(any interface{}) []string {
t := reflect.TypeOf(any)
var handles []string
for k, v := range interfaceMap {
if t.Implements(v) {
handles = append(handles, k)
}
}
return handles
}
英文:
You can use reflect, notice that to get the type of an interface the only way is to use reflect.TypeOf((*INTERFACE)(nil)).Elem()
, here's a working example:
var interfaceMap = map[string]reflect.Type{
"One": reflect.TypeOf((*InterOne)(nil)).Elem(),
....
}
func doesHandle(any interface{}) []string {
t := reflect.TypeOf(any)
var handles []string
for k, v := range interfaceMap {
if t.Implements(v) {
handles = append(handles, k)
}
}
return handles
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论