【发布时间】:2017-01-02 11:48:48
【问题描述】:
Golang 新手在这里。
这个问题的简短版本是:给定一个可能是别名类型的接口值,检查它是否属于底层类型的正确方法是什么?
我发现类型断言和类型切换不起作用。
例如,在下面的程序中,我有一堆从基础类型Origin 自动生成的命名类型Alias<N>。我有一个接口变量v,它可以是任何类型。如果v 的类型为Origin,我想使用它的Field 值。
package main
import (
"fmt"
)
type Origin struct {
Field int
}
type Alias1 Origin
type Alias2 Origin
type Alias3 Origin
// A bunch of other aliases
func f(v interface{}) {
if _, ok := v.(Origin); ok {
fmt.Println("type assertion works")
}
switch v := v.(type) {
case Origin:
fmt.Println("type switch works")
case Alias1:
fmt.Printf("No... Alias1 Value: %v\n", v.Field)
case Alias2:
fmt.Printf("No... Alias2 Value: %v\n", v.Field)
default:
fmt.Printf("No... Alias3 Value: %T\n", v.(Origin).Field)
}
}
func main() {
f(Alias1{Field: 10})
f(Alias2{Field: 10})
f(Alias3{Field: 10})
}
输出如https://play.golang.org/p/3WjpX6NcfF:
No... Alias1 Value: 10
No... Alias2 Value: 10
panic: interface conversion: interface is main.Alias3, not main.Origin
正确的方法是什么? (我无法在f 中列出Origin 的所有别名类型,因为这些别名类型是自动生成并分散在各处的。)非常感谢任何帮助。提前致谢!
===== 编辑 1 =====
尝试使用reflect 包,但仍然没有解决方案:https://play.golang.org/p/3LtG9ZOkQd
package main
import (
"fmt"
"reflect"
)
type Origin struct {
Field int
}
type Alias1 Origin
// A bunch of other aliases
func g(v interface{}) {
vt := reflect.TypeOf(v)
ot := reflect.TypeOf(Origin{})
if vt.ConvertibleTo(ot) {
fmt.Printf("%T is convertible to Origin", v)
// panic: interface is main.Alias3, not main.Origin
// fmt.Printf("Value: %v\n", v.(Origin).Field)
// error: vt is not a type
// fmt.Printf("Value: %v\n", v.(vt).Field)
// error: cannot convert v (type interface {}) to type Origin: need type assertion
// fmt.Printf("Value: %v\n", Origin(v).Field)
}
}
func main() {
g(Alias1{Field: 10})
}
【问题讨论】:
-
只是想 - 可能是逐个字段比较? orig 和 alias 类型的字段集似乎相等play.golang.org/p/TY5eMrN4m9
-
@shibormot 嗯,这似乎并没有什么帮助,因为我仍然不能“使用”
v(接口值)作为Origin类型。即使v的类型与Origin具有相同的字段,编译器也不允许我将v转换为Origin。 -
reflect.ValueOf 和 reflect.Convert 是你的朋友play.golang.org/p/dspem2VnA7
-
但是你想要达到的目标毫无意义。看起来您想为结构和“别名”添加行为 - 使用 GetField 和 SetField 方法定义接口。
-
Comparing with a private interface 的相关/可能重复。