081-反射(Kind)
Posted --Allen--
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Ptr
Slice
String
Struct
UnsafePointer
)
举几个例子:
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 (v Value) Kind() Kind
在上一节我们就已经学会了如果通过变量来获取 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
fmt.Println()
3. 总结
- 掌握 Kind 的定义
- 知道常见的 Kind 有哪些
知道了判断某个类型的 Kind 以后,一切就好办了,如果是数值类型,我们可以直接使用 %d
或 %f
将其格式化,如果是 Struct 类型,我们可以枚举出这个 Struct 所有的字段名,以及字段名对应的值。
以上是关于081-反射(Kind)的主要内容,如果未能解决你的问题,请参考以下文章
go语言学习笔记 — 进阶 — 反射:反射的类型对象(reflect.Type)— 反射类型对象的类型名(Type)和种类(Kind)