使用reflect.Typeof()的golang类型断言

dor*_*yle 13 types typeof go assertion

我试图用字符串值(名称)来识别结构. reflect.TypeOf回报Type.

但类型断言需要一个type.

我怎样才能铸造Typetype

或任何处理它的建议?

http://play.golang.org/p/3PJG3YxIyf

package main

import (
"fmt"
"reflect"
)
type Article struct {
    Id             int64       `json:"id"`
    Title          string      `json:"title",sql:"size:255"`
    Content        string      `json:"content"`
}


func IdentifyItemType(name string) interface{} {
    var item interface{}
    switch name {
    default:
        item = Article{}
    }
    return item
}

func main() {

    i := IdentifyItemType("name")
    item := i.(Article)
    fmt.Printf("Hello, item : %v\n", item)
    item2 := i.(reflect.TypeOf(i))  // reflect.TypeOf(i) is not a type
    fmt.Printf("Hello, item2 : %v\n", item2)

}
Run Code Online (Sandbox Code Playgroud)

new*_*cct 6

从语法上讲,类型断言在括号中采用类型,而不是表达式。因此,这是一个语法错误。

您似乎正在尝试使用在运行时计算出的值来进行类型声明。那有意义吗?让我们考虑一下什么是类型断言。

类型断言由两部分组成:

  1. 在编译时:导致结果表达式具有所需的编译时类型。该表达式x.(T)具有编译时类型T。这使您可以填充您可以使用type进行的表达式T,而您可能无法使用type进行处理x
  2. 在运行时:它检查该值是否不是nil给定类型,并且实际上是否为给定类型,如果不是,则引起恐慌。

第一部分显然对于在运行时计算的类型没有意义。结果表达式的编译时类型不能依赖于编译时未知的内容。

第二个(运行时检查)可以使用在运行时计算的类型来完成。就像是:

if reflect.TypeOf(x) != someTypeComputedAtRuntime {
    panic(42)
}
Run Code Online (Sandbox Code Playgroud)


Mon*_*per 6

如果你需要打开外部接口{}的类型,你就不需要反射.

switch x.(type){
  case int: 
    dosomething()
}
Run Code Online (Sandbox Code Playgroud)

...但是如果你需要在界面中打开属性的类型,那么你可以这样做:

s := reflect.ValueOf(x)
for i:=0; i<s.NumValues; i++{
  switch s.Field(i).Interface().(type){
    case int: 
      dosomething()
  }
}
Run Code Online (Sandbox Code Playgroud)

我没有找到更清洁的方式,我很想知道它是否存在.


hob*_*bbs 6

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

\n\n

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

\n\n

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

\n\n

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

\n


小智 3

我认为您在这里寻找的是类型开关。 https://tour.golang.org/methods/16