web-dev-qa-db-ja.com

Reflect.Typeof()を使用したgolangタイプアサーション

文字列値(名前)で構造体を識別しようとしました。 reflect.TypeOfTypeを返します。

ただし、型アサーションにはtypeが必要です。

Typetypeにキャストするにはどうすればよいですか?

またはそれを処理するための提案はありますか?

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)

}
15
dorajistyle

型のアサーションは、構文上、式ではなく括弧内に型をとります。したがって、これは構文エラーです。

実行時に計算された値を使用して型アサーションを実行しようとしているようです。それは理にかなっていますか?型アサーションとは何かについて考えてみましょう。

型アサーションは次の2つで構成されます。

  1. コンパイル時:結果の式に必要なコンパイル時の型を設定します。式x.(T)のコンパイル時の型はTです。これにより、タイプTで実行できる式を実行できますが、タイプxでは実行できない場合があります。
  2. 実行時:値がnilではなく、実際に指定されたタイプであるかどうかをチェックし、そうでない場合はパニックを引き起こします。

最初の部分は、実行時に計算される型には明らかに意味がありません。結果の式のコンパイル時の型は、コンパイル時に不明なものに依存することはできません。

2つ目(実行時チェック)は、実行時に計算された型で実行できます。何かのようなもの:

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

外部インターフェースのタイプをオンにする必要がある場合は、{}リフレクションは必要ありません。

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

私はもっ​​とすっきりした方法を見つけていません。それが存在するかどうか知りたいです。

5
MondayPaper

ここで探しているのはタイプスイッチだと思います。 https://tour.golang.org/methods/16

3
Nano

ノイズを処理し、すべてのタイプが実装する追加のメソッドを実装できる場合。 '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)
        }
1
rjarmstrong

ValueOfを使用してこれを解決できると思います

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