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

Я попытался идентифицировать структуру со строковым значением (именем). 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)

}

person dorajistyle    schedule 12.01.2015    source источник
comment
В Go это совершенно невозможно. Утверждение типа утверждает только фиксированный статический тип с постоянной времени компиляции. Вы должны переработать свое решение.   -  person Volker    schedule 12.01.2015


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

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

person MondayPaper    schedule 02.09.2015
comment
Но это только для определенных типов, а не для пользовательского типа. Что, если я хочу сделать утверждение типа для настраиваемых типов структур? - person TomSawyer; 13.03.2018
comment
В моем втором примере вы можете размышлять о любой структуре. Тип int - это просто пример обнаружения атрибутов в структуре при циклическом обходе каждого атрибута. - person MondayPaper; 22.03.2018
comment
Я имею в виду, что нам все еще нужно перебирать каждый тип, который у нас есть. Невозможно использовать тип reflect.TypeOf, а затем использовать его для преобразования типа или преобразования типа по строке x. (Customtype) - person TomSawyer; 23.03.2018
comment
Нет, для этого вам понадобятся дженерики :( - person MondayPaper; 26.03.2018

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

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

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

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

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

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

if reflect.TypeOf(x) != someTypeComputedAtRuntime {
    panic(42)
}
person newacct    schedule 20.01.2015

Я думаю, что вы ищете здесь переключатель типа. https://tour.golang.org/methods/16

person Nano    schedule 13.01.2015

Если вы можете справиться с шумом и реализовать дополнительный метод, который реализуют все типы, например '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)
        }
person rjarmstrong    schedule 25.08.2016

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

item2 :=  reflect.ValueOf(i)
fmt.Printf("Hello, item2 : %v\n", item2)
person Pedro Fillastre    schedule 02.09.2015
comment
ValueOf () возвращает отражающий тип. Значение не является фактическим базовым типом интерфейса ... - person prl900; 09.06.2016