Як знайти тип об’єкта в Go?


387

Як знайти тип об’єкта в Go? У Python я просто використовую typeofдля отримання типу об'єкта. Аналогічно в Go, чи є спосіб реалізувати те саме?

Ось контейнер, з якого я повторюю:

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

Я не в змозі отримати тип об'єктних ліній у цьому випадку, який є масивом рядків.


Стандартний довідник не працює в моїй програмі. Я повинен був включити вихідний код мій поганий.
Рахул

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


відобразити не працює для мене. Я оновив питання. У цьому випадку я включив фрагмент коду.
Рахул

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

Кожен метод має різні випадки найкращого використання:

  • форматування рядків - короткий і низький слід (не потрібно імпортувати пакет відображення)

  • пакет відображення - коли потрібно більше деталей про тип, ми маємо доступ до повних можливостей відображення

  • твердження типу - дозволяє групувати типи, наприклад розпізнавати всі типи int32, int64, uint32, uint64 як "int"


3
Здається, ви можете позбутися змінної t, так t := v.(type)стає v.(type)і _ = tбільше не потрібна.
Акавал


case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). Пакет fmt, використовуючи відображення для типу друку
Fantasy_RQG

50

Використовуйте пакет відображення :

Пакетне відображення реалізує відображення часу виконання, дозволяючи програмі маніпулювати об'єктами довільних типів. Типовим способом є прийняття значення за допомогою інтерфейсу статичного типу {} та вилучення його інформації про динамічний тип за допомогою виклику TypeOf, який повертає Type.

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

Ігровий майданчик


відображає лише стандартні типи. Я не в змозі отримати типи елементів контейнера списку.
Рахул

Я оновив свою відповідь, щоб включити фрагмент рядків. Відображає роботи для будь-якого типу. Будь ласка, прочитайте документи: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection має бути достатньо, хоча є багато питань, пов'язаних із відображенням у програмі Go, які також можуть вам допомогти.
Intermernet

2
так, як я можу визначити, чи є тип рядка? if reflect.TypeOf(err) == string?
Олександр Міллс

43

Щоб отримати рядкове представлення:

Від http://golang.org/pkg/fmt/

% T a Синтаксичне подання типу значення

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

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

Ви можете перевірити тип будь-якої змінної / екземпляра під час виконання або за допомогою функції "відображення" пакетів, 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.

  • Основний тип (наприклад: int, string): він повертає його ім'я (наприклад: int, string)
  • STRUCT: він буде повертати що - то в форматі <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: Reflection.TypeOf функція: щоб використовувати цю функцію, вам слід імпортувати "відбивати"

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

3: refle.ValueOf (X) .Kind () : для використання цієї функції вам слід імпортувати "відбивати"

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.