golang type assertion using reflect.Typeof()

℡╲_俬逩灬. 提交于 2019-11-27 02:42:19

问题


I've tried to identify a struct with string value(name). reflect.TypeOf returns Type.

But type assertion needs a type.

How can I casting Type to type?

Or any suggestion to handle it?

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)

}

回答1:


A type assertion, syntactically, takes a type in the parentheses, not an expression. So it is a syntax error.

You seem to be trying to do a type assertion with a value computed at runtime. Does that make sense? Let's think about what a type assertion is.

A type assertion consists of two things:

  1. At compile time: It causes the resulting expression to have the desired compile-time type. The expression x.(T) has compile-time type T. This allows you to do stuff the expression that you can do with type T, which you may not be able to do with the type of x.
  2. At runtime: It checks whether the value is not nil and is actually of the given type, and if not, it causes a panic.

The first part obviously doesn't make sense for a type computed at runtime. The compile-time type of the resulting expression cannot depend on something that is not known at compile-time.

The second one (runtime check) can be done with a type computed at runtime. Something like:

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



回答2:


If you need to switch on the type of the outer interface{} you wont need reflection.

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

...but if you need to switch on the type of the attributes in an interface then you can do this:

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

I haven't found a cleaner way, I'd love to know if it exists.




回答3:


I think what you're looking for here is a type switch. https://tour.golang.org/methods/16




回答4:


If you can handle the noise and implement an extra method which all the types implement e.g. 'Type() string', you can do something like this:

        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:


I think you can use ValueOf to solve this

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


来源:https://stackoverflow.com/questions/27900568/golang-type-assertion-using-reflect-typeof

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!