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

时间:2015-01-12 11:06:01

标签: types go typeof assertion

我试图用字符串值(名称)来识别结构。 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)

}

5 个答案:

答案 0 :(得分:5)

类型断言,在语法上,在括号中采用一种类型,而不是表达式。所以这是一个语法错误。

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

类型断言包含两件事:

  1. 在编译时:它导致生成的表达式具有所需的编译时类型。表达式x.(T)具有编译时类型T。这使您可以使用类型T执行表达式,x可能无法执行该操作。
  2. 在运行时:它检查值是否不是nil并且实际上是给定类型,如果不是,则会导致恐慌。
  3. 对于在运行时计算的类型,第一部分显然没有意义。结果表达式的编译时类型不能依赖于编译时未知的内容。

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

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

答案 1 :(得分:5)

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

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()
  }
}

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

如果您能够处理噪音并实施所有类型实施的额外方法,例如'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)
        }

答案 4 :(得分:0)

我认为您可以使用ValueOf来解决此问题

var myMoment = moment('YYYY-MM-17', 'YYYY-MM-DD', true);

console.log(myMoment.isValid()); // -> false

console.log(myMoment.get('year')); // -> 2016
console.log(myMoment.get('month')); // -> 4
console.log(myMoment.get('day')); // -> 0