2015-01-12 2 views
11

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

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

} 
+6

Это невозможно в Go.Утверждение типа утверждает только фиксированный статический тип постоянной времени компиляции. Вы должны переделать свое решение. – Volker

+0

Спасибо за комментарий. Это очень ясно! – dorajistyle

ответ

4

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

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

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

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

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

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

if reflect.TypeOf(x) != someTypeComputedAtRuntime { 
    panic(42) 
} 
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() 
    } 
} 

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

0

Я думаю, что вы можете использовать ValueOf решить эту

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

ValueOf() возвращает тип reflection.Value не фактический базовый тип интерфейса ... – MonkeyButter

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

 Смежные вопросы

  • Нет связанных вопросов^_^