Làm thế nào để tìm loại đối tượng trong Go?


387

Làm cách nào để tìm loại đối tượng trong Go? Trong Python, tôi chỉ sử dụng typeofđể tìm nạp loại đối tượng. Tương tự như vậy trong Go, có cách nào để thực hiện tương tự không?

Đây là container mà tôi đang lặp đi lặp lại:

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

Tôi không thể có được các loại đối tượng trong trường hợp này là một chuỗi các chuỗi.


Các tài liệu tham khảo tiêu chuẩn không làm việc trong chương trình của tôi. Tôi nên bao gồm mã nguồn xấu của tôi.
Raul

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

Câu trả lời:


470

Gói phản chiếu Go có các phương thức để kiểm tra loại biến.

Đoạn mã sau sẽ in ra loại phản xạ của một chuỗi, số nguyên và float.

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

}

Đầu ra:

Hello, playground
string
int
float64

xem: http://play.golang.org/p/XQMcUVsOja để xem nó hoạt động.

Thêm tài liệu ở đây: http://golang.org/pkg/reflect/#Type


phản ánh không làm việc cho tôi. Tôi đã cập nhật câu hỏi. Tôi đã bao gồm đoạn mã trong trường hợp này.
Raul

462

Tôi đã tìm thấy 3 cách để trả về kiểu của biến khi chạy:

Sử dụng định dạng chuỗi

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

Sử dụng gói phản ánh

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

Sử dụng xác nhận kiểu

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

Mỗi phương pháp có một trường hợp sử dụng tốt nhất khác nhau:

  • định dạng chuỗi - dấu chân ngắn và thấp (không cần thiết để nhập gói phản ánh)

  • gói phản ánh - khi cần thêm chi tiết về loại chúng tôi có quyền truy cập vào các khả năng phản chiếu đầy đủ

  • xác nhận kiểu - cho phép nhóm các loại, ví dụ nhận ra tất cả các loại int32, int64, uint32, uint64 là "int"


3
Dường như bạn có thể thoát khỏi biến t, vì vậy t := v.(type)trở thành v.(type), và _ = tkhông còn cần thiết.
Akavall

3
Dựa trên điểm chuẩn của barebones, cách tiếp cận phản xạ hiệu quả hơn đáng ngạc nhiên là gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). gói fmt sử dụng phản chiếu để in loại
Fantasy_RQG

50

Sử dụng gói phản ánh :

Gói phản ánh thực hiện phản xạ thời gian chạy, cho phép một chương trình thao tác với các đối tượng với các loại tùy ý. Việc sử dụng thông thường là lấy một giá trị với giao diện loại tĩnh {} và trích xuất thông tin loại động của nó bằng cách gọi TypeOf, trả về Loại.

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

Sản xuất:

bool
string
int
float64
[]string

Sân chơi

Ví dụ sử dụng 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
}

Sản xuất:

bool
string
int
float64
string

Sân chơi


phản ánh chỉ hiển thị các loại tiêu chuẩn. Tôi không thể có được các loại yếu tố của một thùng chứa danh sách.
Raul

Tôi đã cập nhật câu trả lời của mình để bao gồm một lát dây. Reflect hoạt động cho bất kỳ loại. Vui lòng đọc các tài liệu: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection là đủ, mặc dù có nhiều câu hỏi SO liên quan đến phản xạ trong Go cũng sẽ giúp bạn hiểu.
Intermernet

2
ughhh, làm thế nào tôi có thể xác định nếu loại là một chuỗi? if reflect.TypeOf(err) == string?
Alexander Mills

43

Để có được một chuỗi đại diện:

Từ http://golang.org/pkg/fmt/

% T một biểu diễn cú pháp của loại giá trị

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

Đầu ra:

string
int
float64
bool

cách tiếp cận rất thực dụng +1
Bijan

16

Tôi sẽ tránh xa sự phản ánh. gói. Thay vào đó hãy sử dụng% 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

Cách tốt nhất là sử dụng khái niệm phản chiếu trong Google.
reflect.TypeOfđưa ra loại cùng với tên gói
reflect.TypeOf().Kind()cho loại gạch chân


1
Điều này tôi nghĩ là một câu trả lời tốt hơn
Ezio

9

Để ngắn gọn, vui lòng sử dụng fmt.Printf("%T", var1) hoặc các biến thể khác của nó trong gói fmt.


4

Bạn có thể kiểm tra loại của bất kỳ biến / thể hiện nào trong thời gian chạy bằng cách sử dụng TypeOfchức năng gói "phản ánh" hoặc bằng cách sử dụng 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

Để có được các loại trường trong struct

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

Đầu ra

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

Xem trong IDE https://play.golang.org/p/bwIpYnBQiE


0

bạn có thể sử dụng reflect.TypeOf.

  • loại hình cơ bản (ví dụ: int, string): nó sẽ trở lại tên gọi của nó (ví dụ: int, string)
  • struct: nó sẽ trả về một cái gì đó trong định dạng <package name>.<struct name>(ví dụ main.test:)

0

Nếu chúng ta có các biến này:

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

Định dạng 1: fmt.Printf% T : để sử dụng tính năng này, bạn nên nhập "fmt"

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

Hàm 2: Refl.TypeOf : để sử dụng tính năng này, bạn nên nhập "phản ánh"

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

3: Refl.ValueOf (X) .Kind () : để sử dụng tính năng này, bạn nên nhập "phản ánh"

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

0

Bạn có thể sử dụng: interface{}..(type)như trong sân chơi này

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


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.