文字列値(名前)で構造体を識別しようとしました。 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)
}
型のアサーションは、構文上、式ではなく括弧内に型をとります。したがって、これは構文エラーです。
実行時に計算された値を使用して型アサーションを実行しようとしているようです。それは理にかなっていますか?型アサーションとは何かについて考えてみましょう。
型アサーションは次の2つで構成されます。
x.(T)
のコンパイル時の型はT
です。これにより、タイプT
で実行できる式を実行できますが、タイプx
では実行できない場合があります。nil
ではなく、実際に指定されたタイプであるかどうかをチェックし、そうでない場合はパニックを引き起こします。最初の部分は、実行時に計算される型には明らかに意味がありません。結果の式のコンパイル時の型は、コンパイル時に不明なものに依存することはできません。
2つ目(実行時チェック)は、実行時に計算された型で実行できます。何かのようなもの:
if reflect.TypeOf(x) != someTypeComputedAtRuntime {
panic(42)
}
外部インターフェースのタイプをオンにする必要がある場合は、{}リフレクションは必要ありません。
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()
}
}
私はもっとすっきりした方法を見つけていません。それが存在するかどうか知りたいです。
ここで探しているのはタイプスイッチだと思います。 https://tour.golang.org/methods/16
ノイズを処理し、すべてのタイプが実装する追加のメソッドを実装できる場合。 '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)
}
ValueOfを使用してこれを解決できると思います
item2 := reflect.ValueOf(i)
fmt.Printf("Hello, item2 : %v\n", item2)