如何在Golang中获取结构体字段类型?

3
type Role int

type User struct {
    Id int64
    Name string
    Role Role
}

func ListFields(a interface{}) {
    v := reflect.ValueOf(a).Elem()
    for j := 0; j < v.NumField(); j++ {
        f := v.Field(j)
        n := v.Type().Field(j).Name
        t := f.Type().String()
        fmt.Printf("Name: %s  Kind: %s  Type: %s\n", n, f.Kind(), t)
    }
}

func main() {

    var u User
    ListFields(&u)
}

运行 main.go:go run main.go

名称:Id 类型:int64 类别:int64

名称:Name 类型:string 类别:string

名称:Role 类型:main.Role 类别:int <--- 如何获取 int 类型?


反射API没有提供一种获取某些类型的底层类型的方法。在这个例子中,无法从reflect.TypeOf(Role(0))获取reflect.TypeOf(int(0))。您可以使用Type.Kind来反映底层类型。为什么需要获取int类型? - Charlie Tumahai
@CeriseLimón 谢谢,我忽略了 Kind() 方法。 - Neal
1个回答

1
在Go中,Kind()返回基本类型(这就是您要求的内容),Type()返回直接类型(即您定义的自定义类型)。您永远无法从Type()中获取任何自定义类型的基本类型。我稍微修改了您的示例,以帮助您理解,Kind()始终返回实际的基本类型(或类型的种类,请参见https://golang.org/pkg/reflect/#Kind),尽管存在许多嵌套的自定义类型。
package main

import (
    "fmt"
    "reflect"
)

type Role int
type Role2 Role
type Role3 Role2

type User struct {
    Id   int64
    Name string
    Role Role3
}

func ListFields(a interface{}) {
    v := reflect.ValueOf(a).Elem()
    for j := 0; j < v.NumField(); j++ {
        f := v.Field(j)
        n := v.Type().Field(j).Name
        t := f.Type().String()
        fmt.Printf("Name: %s  Basic Type or Kind: %s  Direct or Custom Type: %s\n", n, f.Kind(), t)
    }
}

func main() {

    var u User
    ListFields(&u)
}

https://goplay.space/#-eTlN4dGzj_k

换句话说,Kind和Type都是类型。它们适用于基本类型(int64、string等),但对于自定义类型则不同。没有理由用Kind替换Type的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接