2

我正在尝试在 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)
}

感谢您的回答。

4

1 回答 1

5

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

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

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

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

于 2020-01-30T06:36:04.877 回答