Golang newbie here.
The short version of this question is: given an interface value which could be of an aliased type, what's the proper way to check whether it is of an underlying type?
I found that type assertion and type switch doesn't work.
For example, in the following program, I have a bunch of automatically generated named types Alias<N>
from an underlying type Origin
. And I have an interface variable v
, which could be of any type. I'd like to use its Field
value if v
is of type Origin
.
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
", v.Field)
case Alias2:
fmt.Printf("No... Alias2 Value: %v
", v.Field)
default:
fmt.Printf("No... Alias3 Value: %T
", v.(Origin).Field)
}
}
func main() {
f(Alias1{Field: 10})
f(Alias2{Field: 10})
f(Alias3{Field: 10})
}
Output as shown in https://play.golang.org/p/3WjpX6NcfF:
No... Alias1 Value: 10
No... Alias2 Value: 10
panic: interface conversion: interface is main.Alias3, not main.Origin
What would be the correct way? (I cannot list all aliased types of Origin
in f
since those aliased types are automatically generated and scattered around.) Any help is highly appreciated. Thanks in advance!
===== Edit 1 =====
Tried to use the reflect
package, but still don't have the solution: 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
", v.(Origin).Field)
// error: vt is not a type
// fmt.Printf("Value: %v
", v.(vt).Field)
// error: cannot convert v (type interface {}) to type Origin: need type assertion
// fmt.Printf("Value: %v
", Origin(v).Field)
}
}
func main() {
g(Alias1{Field: 10})
}