Утверждение типа golang с использованием reflect.Typeof()

Я попытался идентифицировать структуру со строковым значением (name). reflect.TypeOf возвращает Type.

Но для утверждения типа требуется a 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)

}

Ответ 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()
  }
}

Я не нашел более чистого способа, я бы хотел знать, существует ли он.

Ответ 2

Утверждение типа, синтаксически, принимает тип в круглых скобках, а не выражение. Таким образом, это синтаксическая ошибка.

Кажется, вы пытаетесь сделать утверждение типа со значением, вычисленным во время выполнения. Имеет ли это смысл? Подумайте о том, что такое утверждение типа.

Утверждение типа состоит из двух вещей:

  • Во время компиляции: это приводит к тому, что результирующее выражение имеет желаемый тип времени компиляции. Выражение x.(T) имеет тип времени компиляции T. Это позволяет вам делать то, что вы можете сделать с типом T, который вы, возможно, не сможете сделать с типом x.
  • Во время выполнения: он проверяет, не является ли значение nil и фактически является данным типом, а если нет, это вызывает панику.

Первая часть, очевидно, не имеет смысла для типа, вычисленного во время выполнения. Тип времени компиляции результирующего выражения не может зависеть от того, что неизвестно во время компиляции.

Вторая (проверка времени выполнения) может быть выполнена с помощью типа, вычисленного во время выполнения. Что-то вроде:

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

Ответ 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)
        }
        return

Ответ 5

Я думаю, вы можете использовать ValueOf для решения этой проблемы.

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