【问题标题】:How to use type assertion from interface reflection in golang?如何在golang中使用接口反射的类型断言?
【发布时间】:2020-05-15 17:10:12
【问题描述】:

我正在尝试在 golang 中使用类型断言。 直接断言没有问题。

a, ok := i.(MyStruct)

但是当我使用反射时

b, ok := i.(reflect.TypeOf(i))

我遇到了一个错误。那有什么问题?以及如何处理?

完整代码:

package main

import (
     "fmt"
     "reflect"
)

type MyStruct struct {
    field string
}

func main() {
    var i interface{} = MyStruct{field:"Thanks"}

    a, ok := i.(MyStruct)
    fmt.Println(a, ok)

    t := reflect.TypeOf(i)
    fmt.Println(t)

    b, ok := i.(t)
    fmt.Println(b, ok)
}

感谢您的回答。

【问题讨论】:

  • 12 的可能重复

标签: go types interface assertion reflect


【解决方案1】:

很多东西,但基本上“它不会那样工作”。类型断言中括号内的内容必须是type,即类型名称或类型文字。 reflect.TypeOf(i) 不是其中之一,它是一个方法调用表达式。因此这是一个语法错误。 reflect.TypeOf 不会“返回类型”(这在 Go 中并不是真正可以做的事情),它返回一个 reflect.Type,这是一个普通的 go 结构,其中包含 关于 的信息一种类型(即一种元类型)。

但它不起作用的更根本原因是因为它不能...Go 需要在声明变量时知道它的类型。它的类型要么在var 声明中明确给出,要么从var x = value 声明或x := value 短赋值中的初始化值类型推断。在编译时类型未知是不可能的。 Go 不允许您编写产生未确定类型的表达式。

类型断言的真正目的是获取接口类型的值(这是一种“盒子”,可以保存多种类型的值,或者对于interface{},可以保存任何类型)并检索特定具体类型的值。断言产生的值将具有断言命名的类型,没有其他类型。 (在 ,ok 赋值的情况下,如果断言失败,变量将持有 zero value 但仍然是正确的类型)。如果您可以将断言写入仅在运行时才知道的类型,那么整个事情就会崩溃,所以您不能编写它——这是一个错误。

简而言之,您不能使用反射来做到这一点。您可以使用反射来了解i 的类型,可以了解该类型的名称,可以了解其底层Kind 是Struct,您可以枚举结构的字段并从中获取值等。 ..所有这些都是反射的合法用途。但是它不能给你一个MyStruct类型的变量——方法是i.(MyStruct)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-11
    • 2015-03-10
    • 2014-01-22
    • 1970-01-01
    • 2016-10-03
    • 2019-01-01
    • 2019-11-03
    • 1970-01-01
    相关资源
    最近更新 更多