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.