Goでオブジェクトのタイプを見つける方法は?


387

Goでオブジェクトのタイプを見つけるにはどうすればよいですか?Pythonでは、typeofオブジェクトのタイプを取得するために使用します。同様にGoで、同じものを実装する方法はありますか?

これが私が反復しているコンテナです:

for e := dlist.Front(); e != nil; e = e.Next() {
    lines := e.Value
    fmt.Printf(reflect.TypeOf(lines))
}

この場合、文字列の配列であるオブジェクト行のタイプを取得できません。


私のプログラムで動作していない標準リファレンス。私はソースコードを私の悪いものに含めるべきだった。
Rahul、2013年

5
fmt.Printf("%T\n", var)
まあまあ

回答:


470

Goリフレクションパッケージには、変数のタイプを検査するためのメソッドがあります。

次のスニペットは、文字列、整数、および浮動小数点のリフレクションタイプを出力します。

package main

import (
    "fmt"
    "reflect"
)

func main() {

    tst := "string"
    tst2 := 10
    tst3 := 1.2

    fmt.Println(reflect.TypeOf(tst))
    fmt.Println(reflect.TypeOf(tst2))
    fmt.Println(reflect.TypeOf(tst3))

}

出力:

Hello, playground
string
int
float64

動作を確認するには、http//play.golang.org/p/XQMcUVsOjaを参照してください。

その他のドキュメントはこちら:http : //golang.org/pkg/reflect/#Type


私のために働いていない反省。質問を更新しました。この場合、コードスニペットを含めました。
Rahul、2013年

462

実行時に変数の型を返す3つの方法を見つけました。

文字列フォーマットの使用

func typeof(v interface{}) string {
    return fmt.Sprintf("%T", v)
}

リフレクトパッケージの使用

func typeof(v interface{}) string {
    return reflect.TypeOf(v).String()
}

型アサーションの使用

func typeof(v interface{}) string {
    switch v.(type) {
    case int:
        return "int"
    case float64:
        return "float64"
    //... etc
    default:
        return "unknown"
    }
}

すべての方法には、異なる最良の使用例があります。

  • 文字列のフォーマット-短いフットプリント(reflectパッケージをインポートする必要はありません)

  • リフレクトパッケージ-完全なリフレクション機能にアクセスできるタイプの詳細が必要な場合

  • タイプの表明-グループ化タイプを許可します。たとえば、すべてのint32、int64、uint32、uint64タイプを「int」として認識します。


3
あなたが変数を取り除くことができているようですtので、t := v.(type)なり、v.(type)_ = tもう必要ありません。
Akavall 2017

3
ベアボーンベンチマークに基づくリフレクトアプローチは、驚くほど効率的ですgist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String())。印刷タイプに反映を使用するfmtパッケージ
Fantasy_RQG

50

リフレクトパッケージを使用ます。

パッケージreflectは実行時リフレクションを実装し、プログラムが任意のタイプのオブジェクトを操作できるようにします。一般的な使用法は、静的型インターフェイス{}で値を取得し、Typeを返すTypeOfを呼び出して動的型情報を抽出することです。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Println(reflect.TypeOf(b))
    fmt.Println(reflect.TypeOf(s))
    fmt.Println(reflect.TypeOf(n))
    fmt.Println(reflect.TypeOf(f))
    fmt.Println(reflect.TypeOf(a))
}

生成する:

bool
string
int
float64
[]string

遊び場

使用例ValueOf(i interface{}).Kind()

package main

import (
    "fmt"
    "reflect"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Println(reflect.ValueOf(b).Kind())
    fmt.Println(reflect.ValueOf(s).Kind())
    fmt.Println(reflect.ValueOf(n).Kind())
    fmt.Println(reflect.ValueOf(f).Kind())
    fmt.Println(reflect.ValueOf(a).Index(0).Kind()) // For slices and strings
}

生成する:

bool
string
int
float64
string

遊び場


標準タイプのみを表示します。リストコンテナーの要素の種類を取得できません。
Rahul、2013年

文字列のスライスを含めるように回答を更新しました。リフレクトはどのタイプでも機能します。ドキュメントをお読みください:golang.org/pkg/reflectblog.golang.org/laws-of-reflectionは同様にあなたを助ける必要があるゴーでの反射に関連する多くのSOの質問がありますが、十分なはずです。
Intermernet 2013年

2
うーん、型が文字列かどうかはどうすればわかりますか?if reflect.TypeOf(err) == string
Alexander Mills

43

文字列表現を取得するには:

http://golang.org/pkg/fmt/から

%T値のタイプのGo構文表現

package main
import "fmt"
func main(){
    types := []interface{} {"a",6,6.0,true}
    for _,v := range types{
        fmt.Printf("%T\n",v)
    }
}

出力:

string
int
float64
bool

非常に実用的なアプローチ+1
Bijan 2014

16

私は反射から離れて滞在します。パッケージ。代わりに%Tを使用します

package main

import (
    "fmt"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Printf("%T\n", b)
    fmt.Printf("%T\n", s)
    fmt.Printf("%T\n", n)
    fmt.Printf("%T\n", f)
    fmt.Printf("%T\n", a)
 }

13

最善の方法は、Googleでリフレクションの概念を使用することです。
reflect.TypeOfタイプをパッケージ名とともに
reflect.TypeOf().Kind()与える下線を引くタイプを与える


1
これは私がより良い答えだと思います
エツィオ

9

簡単に言うfmt.Printf("%T", var1) と、fmtパッケージに含まれている、または他のバリアントを使用してください。


4

「reflect」パッケージTypeOf関数を使用するか、次のコマンドを使用して、実行時に変数/インスタンスのタイプを確認できますfmt.Printf()

package main

import (
   "fmt"
   "reflect"
)

func main() {
    value1 := "Have a Good Day"
    value2 := 50
    value3 := 50.78

    fmt.Println(reflect.TypeOf(value1 ))
    fmt.Println(reflect.TypeOf(value2))
    fmt.Println(reflect.TypeOf(value3))
    fmt.Printf("%T",value1)
    fmt.Printf("%T",value2)
    fmt.Printf("%T",value3)
}

4

構造体のフィールドのタイプを取得するには

package main

import (
  "fmt"
  "reflect"
)

type testObject struct {
  Name   string
  Age    int
  Height float64
}

func main() {
   tstObj := testObject{Name: "yog prakash", Age: 24, Height: 5.6}
   val := reflect.ValueOf(&tstObj).Elem()
   typeOfTstObj := val.Type()
   for i := 0; i < val.NumField(); i++ {
       fieldType := val.Field(i)
       fmt.Printf("object field %d key=%s value=%v type=%s \n",
          i, typeOfTstObj.Field(i).Name, fieldType.Interface(),
          fieldType.Type())
   }
}

出力

object field 0 key=Name value=yog prakash type=string 
object field 1 key=Age value=24 type=int 
object field 2 key=Height value=5.6 type=float64

IDE https://play.golang.org/p/bwIpYnBQiEを参照してください


0

使用できますreflect.TypeOf

  • 基本タイプ(例:intstring):名前を返します(例:intstring
  • 構造体:それは形式で何かが返されます<package name>.<struct name>(例えば:main.test

0

この変数がある場合:

var counter int = 5
var message string  = "Hello"
var factor float32 = 4.2
var enabled bool = false

1:fmt.Printf%T形式:この機能を使用するには、「fmt」インポートする必要があります

fmt.Printf("%T \n",factor )   // factor type: float32

2:reflect.TypeOf関数:この機能を使用するには、「reflect」インポートする必要があります

fmt.Println(reflect.TypeOf(enabled)) // enabled type:  bool

3:Reflect.ValueOf(X).Kind():この機能を使用するには、「reflect」インポートする必要があります

fmt.Println(reflect.ValueOf(counter).Kind()) // counter type:  int

0

使用できます:interface{}..(type)この遊び場のように

package main
import "fmt"
func main(){
    types := []interface{} {"a",6,6.0,true}
    for _,v := range types{
        fmt.Printf("%T\n",v)
        switch v.(type) {
        case int:
           fmt.Printf("Twice %v is %v\n", v, v.(int) * 2)
        case string:
           fmt.Printf("%q is %v bytes long\n", v, len(v.(string)))
       default:
          fmt.Printf("I don't know about type %T!\n", v)
      }
    }
}


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.