dth54864 2016-08-25 22:14 采纳率: 0%
浏览 35
已采纳

如何测试接口变量的基础类型的接口变量的类型是别名

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})
}
  • 写回答

1条回答 默认 最新

  • dpge74512 2016-08-26 00:05
    关注

    The shortest I can get is this:

    fmt.Printf("Value: %v
    ", reflect.ValueOf(v).Convert(ot).Interface().(Origin).Field)
    

    (instead of third fmt in your code)

    It converts v to origin type using reflection. But then to use type assertion, but that will be reflect.Value. To cast it to type Origin, it needs to be converted to interface{} and then it can be type asserted to Origin type.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C#读写EXCEL文件,不同编译
  • ¥15 如何提取csv文件中需要的列,将其整合为一篇完整文档,并进行jieba分词(语言-python)
  • ¥15 MapReduce结果输出到HBase,一直连接不上MySQL
  • ¥15 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符
  • ¥15 NX MCD仿真与博途通讯不了啥情况
  • ¥15 win11家庭中文版安装docker遇到Hyper-V启用失败解决办法整理
  • ¥15 gradio的web端页面格式不对的问题
  • ¥15 求大家看看Nonce如何配置