Go'da bir nesnenin türü nasıl bulunur?


387

Go'da bir nesnenin türünü nasıl bulurum? Python, sadece typeofnesne türünü almak için kullanın . Go'da da benzer şekilde, bunu uygulamanın bir yolu var mı?

İşte ben yineleme kabı:

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

Dizeleri bir dizi olan bu durumda nesne satırlarının türünü alamıyorum.


Programımda çalışan standart referans değil. Kaynak kodumu kötüme eklemeliydim.
Rahul

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

Yanıtlar:


470

Go yansıma paketi, değişken türlerini denetleme yöntemlerine sahiptir.

Aşağıdaki snippet, bir dize, tamsayı ve kayan noktalı öğenin yansıma türünü yazdırır.

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

}

Çıktı:

Hello, playground
string
int
float64

eylemde görüntülemek için bkz. http://play.golang.org/p/XQMcUVsOja .

Daha fazla doküman burada: http://golang.org/pkg/reflect/#Type


benim için çalışan değil. Soruyu güncelledim. Bu durumda kod pasajını dahil ettim.
Rahul

462

Çalışma zamanında bir değişkenin türünü döndürmek için 3 yol buldum:

Dize biçimlendirmesini kullanma

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

Yansıtma paketini kullanma

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

Tür iddialarını kullanma

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

Her yöntemin farklı bir en iyi kullanım durumu vardır:

  • dize biçimlendirme - kısa ve düşük kaplama alanı (yansıtma paketini içe aktarmak gerekmez)

  • paketi yansıtır - tür hakkında daha fazla ayrıntıya ihtiyaç duyduğumuzda tam yansıma özelliklerine erişebiliriz

  • tür onayları - gruplama türlerine izin verir, örneğin tüm int32, int64, uint32, uint64 türlerini "int" olarak tanıma


3
Değişkenden kurtulabileceğiniz anlaşılıyor t, bu yüzden t := v.(type)oluyor v.(type)ve _ = tartık gerekli değil.
Akavall

3
Bir barebone karşılaştırmasına dayanarak, yansıtma yaklaşımı şaşırtıcı derecede daha verimli gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). fmt paketi yazdırmak için yansıtma türünü kullanarak
Fantasy_RQG

50

Yansıtma paketini kullanın :

Paket yansıtma, çalışma zamanı yansımasını uygulayarak bir programın rasgele türlere sahip nesneleri işlemesine izin verir. Tipik kullanım, statik tür arabirimi {} ile bir değer almak ve bir Tür döndüren TypeOf'u çağırarak dinamik tür bilgilerini ayıklamaktır.

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

üretir:

bool
string
int
float64
[]string

Oyun alanı

Kullanarak örnek 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
}

üretir:

bool
string
int
float64
string

Oyun alanı


refl, yalnızca standart türleri görüntüler. Bir liste kapsayıcısının öğe türlerini alamıyorum.
Rahul

Cevabımı bir dizgi içerecek şekilde güncelledim. Yansıtma her tür için çalışır. Lütfen dokümanları okuyun: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection yeterli olmalı, ancak Go'daki yansımayla ilgili size de yardımcı olacak birçok SO sorusu var.
Intermernet

2
ughhh, türün bir dize olup olmadığını nasıl belirleyebilirim? if reflect.TypeOf(err) == string?
Alexander Mills

43

Dize temsili almak için:

Http://golang.org/pkg/fmt/ adresinden

% T a Değer türünün Go-sözdizimi gösterimi

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

Çıktılar:

string
int
float64
bool

çok pragmatik yaklaşım +1
Bijan

16

Yansıtmadan uzak dururdum. paketlemek. Bunun yerine% T kullanın

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'da yansıma kavramını kullanmanın en iyi yolu.
reflect.TypeOfpaket adıyla birlikte
reflect.TypeOf().Kind()yazı verir alt çizgi tipini verir


1
Bu daha iyi bir cevap olduğunu düşünüyorum
Ezio

9

Kısacası, lütfen fmt.Printf("%T", var1) fmt paketindeki veya diğer varyantlarını kullanın .


4

Herhangi bir değişkenin / örneğin türünü çalışma zamanında "yansıtma" paketleri TypeOfişlevini kullanarak veya aşağıdakileri kullanarak kontrol edebilirsiniz 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

Yapıdaki alan türlerini almak

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

Çıktı

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'ye bakın https://play.golang.org/p/bwIpYnBQiE


0

kullanabilirsiniz reflect.TypeOf.

  • Temel tipi (örn: int, string): bu adı dönecektir (örn: int, string)
  • struct: Bu formatta bir şey dönecektir <package name>.<struct name>(örn: main.test)

0

Bu değişkenlere sahipsek:

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

1: fmt.Printf% T biçimi: bu özelliği kullanmak için "fmt" yi içe aktarmalısınız

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

2: refl.TypeOf işlevi: bu özelliği kullanmak için "yansıtma"

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

3: refll.ValueOf (X) .Kind () : bu özelliği kullanmak için " refl "

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

0

Kullanabilirsiniz: interface{}..(type)bu oyun alanında olduğu gibi

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.