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

Posted

技术标签:

【中文标题】golang 类型断言使用 reflect.Typeof()【英文标题】:golang type assertion using reflect.Typeof() 【发布时间】:2015-03-10 03:15:05 【问题描述】:

我尝试使用字符串值(名称)来识别结构。 reflect.TypeOf 返回Type

但是类型断言需要type

如何将Type 转换为type

或者有什么处理建议?

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)


【问题讨论】:

这在 Go 中是完全不可能的。类型断言仅断言编译时常量固定静态类型。你必须重新设计你的解决方案。 【参考方案1】:

如果需要开启外部接口的类型则不需要反射。

switch x.(type)
  case int: 
    dosomething()

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

s := reflect.ValueOf(x)
for i:=0; i<s.NumValues; i++
  switch s.Field(i).Interface().(type)
    case int: 
      dosomething()
  

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

【讨论】:

但这仅适用于确定的类型,不适用于自定义类型。如果我想为自定义结构类型做类型断言怎么办? 在我的第二个示例中,您可以反映任何结构。 “int”只是一个在结构上循环遍历每个属性时发现属性的示例。 我的意思是我们仍然必须迭代我们拥有的每种类型。无法使用 reflect.TypeOf 的类型,然后将其用于类型转换或通过字符串 x 进行类型转换。("customtype") 不,你需要泛型:(【参考方案2】:

从句法上讲,类型断言采用括号中的类型,而不是表达式。所以是语法错误。

您似乎正在尝试使用在运行时计算的值进行类型断言。那有意义吗?让我们想想什么是类型断言。

类型断言由两部分组成:

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

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

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

if reflect.TypeOf(x) != someTypeComputedAtRuntime 
    panic(42)

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

如果您可以处理噪音并实现所有类型都实现的额外方法,例如'Type() string',你可以这样做:

        ve := &ValidationError
        nf := &NotFound

        switch err.Type() 
        case ve.Type() :
            SendBadRequest(w, err)
        case nf.Type() :
            http.NotFound(w, r)
        default:
            SendInternalError(w, err)
        

【讨论】:

【参考方案5】:

我认为你可以使用 ValueOf 来解决这个问题

item2 :=  reflect.ValueOf(i)
fmt.Printf("Hello, item2 : %v\n", item2)

【讨论】:

ValueOf() 返回一个类型 reflect.Value 不是接口的实际底层类型...

以上是关于golang 类型断言使用 reflect.Typeof()的主要内容,如果未能解决你的问题,请参考以下文章

golang类型断言的使用(Type Assertion)

Golang 类型断言

Golang type assertion 类型断言

Golang type assertion 类型断言

Golang type assertion 类型断言

golang:类型断言基本使用方法