0
点赞
收藏
分享

微信扫一扫

081-反射(Kind)


希望你还能记得反射中的 Type 和 Value 这两个类型。Type 是接口类型,Value 是 Struct 类型;Type 是类型描述,而 Value 是具体的值。

这次,我们来看一下 Golang 反射中的另一个重要概念 —— Kind.

1. Kind 定义

A Kind represents the specific kind of type that a Type represents. The zero Kind is not a valid kind.

Kind 的官方定义如上,它描述的是 Type 被归属于哪一类。在 Golang 里,所有 Type 都能归属到下面这些类别:

type Kind uint

const (
Invalid Kind = iota

举几个例子:

bool // Kind: Bool
int8 // Kind: Int8
type Person struct{ Name string, Age int8} // Kind: Struct
type Second uint64 // Kind: Uint64
type Reader interface{ Read(b byte[]) (int, error) } // Kind: Interface

上面这几个类型,总是能被划分到一个类别。

2. 判断 Kind

Type 和 Value 类型都提供了 Kind 方法,来返回其类型的类别。

// Type 中的 Kind 方法
type Type interface {
...
Kind() Kind
...
}

// Value 中的 Kind 方法
type Value Struct {
...
}
func

在上一节我们就已经学会了如果通过变量来获取 Type 和 Value 对象。下面我们利用 Type 或 Value 来获取 Type 的 Kind 类别。

package main

import (
"fmt"
"reflect"
)

type Second int
type Person struct {
Name string
Age int
}

func main() {
fmt.Println("var s Second") // var s Second
var s Second = 100
t := reflect.TypeOf(s)
fmt.Printf("s.Type.String: %v\n", t.String()) // s.Type.String: main.Second
fmt.Printf("s.Type: %v\n", t) // s.Type: main.Second
k := t.Kind()
fmt.Printf("s.Type.kind: %d:%v\n", k, k) // s.Type.kind: 2:int
fmt.Println()

v := reflect.ValueOf(s)
fmt.Printf("s.Value.String: %v\n", v.String()) // s.Value.String: <main.Second Value>
fmt.Printf("s.Value: %v\n", v) // s.Value: 100
fmt.Println()

k = v.Kind()
fmt.Printf("s.Value.Kind: %d:%v\n", k, k) // s.Value.Kind: 2:int
fmt.Println()

fmt.Println(`var p = Person{"allen", 19}`) // var p = Person{"allen", 19}
var p = Person{"allen", 19}
t = reflect.TypeOf(p)
fmt.Printf("p.Type.String): %v\n", t.String()) // p.Type.String): main.Person
fmt.Printf("p.Type: %v\n", t) // p.Type: main.Person
k = t.Kind()
fmt.Printf("p.Type.kind: %d:%v\n", k, k) // p.Type.kind: 25:struct
fmt.Println()
v = reflect.ValueOf(p)
fmt.Printf("p.Value.String: %v\n", v.String()) // p.Value.String: <main.Person Value>
fmt.Printf("p.Value: %v\n", v) // p.Value: {allen 19}
fmt.Println()
k = v.Kind()

// 注意变量 p 的 Kind,按照 %d 打印出来的是 25,因为 struct 正好对应 25。
fmt.Printf("p.Value.Kind: %d:%v\n", k, k) // s.Value.Kind: 25:struct

3. 总结

  • 掌握 Kind 的定义
  • 知道常见的 Kind 有哪些

知道了判断某个类型的 Kind 以后,一切就好办了,如果是数值类型,我们可以直接使用 ​​%d​​​ 或 ​​%f​​ 将其格式化,如果是 Struct 类型,我们可以枚举出这个 Struct 所有的字段名,以及字段名对应的值。


举报

相关推荐

0 条评论