1-reflect.Type

1 实现文件

gofrontend\libgo\go\reflect\type.go
gofrontend\libgo\go\reflect\value.go

这里定义了内部类型
src\reflect\type.go
src\runtime\type.go

2. reflect.Type

reflect.Type是一个interface.

type Type interface {
...
}

定义了一系列的方法。比如

2.1 公共方法
2.1.1 名称相关:
  1. 类型名称 Name() string
  2. 类型的字符串形式 String() string
2.1.2 类型相关:
  1. 类型的类型值Kind() Kind
  2. 类型是否可以转换ConvertibleTo(u Type) bool
2.1.3 方法相关:
  1. 获取第i个方法。 Method(int) Method
  2. 方法个数. NumMethod() int
  3. 通过名称获取方法 MethodByName(string) (Method, bool)
2.2 不同类型特有方法
2.2.1 子元素类型 Array, Chan, Map, Ptr, or Slice 调用
  1. 返回内部子元素类型 Elem() Type
2.2.2 struct特有方法
  1. 获取第i个字段. Field(i int) StructField
  2. 通过名称获取字段 FieldByName(name string) (StructField, bool)
  3. 字段个数。 NumField() int
2.2.3 map特有方法
  1. 返回key类型,Key() Type
2.2.4 array特有方法
  1. 数组长度 Len() int
2.2.5 func特有方法
  1. 入参个数 NumIn() int
  2. 返回值个数 NumOut() int
  3. 第i个返回值类型 Out(i int) Type
  4. 第i个入参类型 In(i int) Type
2.2.6 chan特有方法
  1. chan方向 ChanDir() ChanDir
type ChanDir int

const (
    RecvDir ChanDir             = 1 << iota // <-chan
    SendDir                                 // chan<-
    BothDir = RecvDir | SendDir             // chan
)
// Create the main IR data structure.
type Type interface {
    Align() int                 // 此类型的变量对齐后所占用的字节数
    FieldAlign() int            // 如果是struct的字段,对齐后占用的字节数
    Method(int) Method          // 返回类型方法集里的第 `i` (传入的参数)个方法
    MethodByName(string) (Method, bool) // 通过名称获取方法
    NumMethod() int             // 获取类型方法集里导出的方法个数
    Name() string               // 类型名称
    PkgPath() string            // 返回类型所在的路径,如:encoding/base64
    Size() uintptr               // 返回类型的大小,和 unsafe.Sizeof 功能类似
    String() string                     // 返回类型的字符串表示形式
    Kind() Kind                         // 返回类型的类型值
    Implements(u Type) bool             // 类型是否实现了接口 u
    AssignableTo(u Type) bool           // 是否可以赋值给 u
    ConvertibleTo(u Type) bool          // 是否可以类型转换成 u
    Comparable() bool                   // 类型是否可以比较
    // 下面这些函数只有特定类型可以调用
    // 如:Key, Elem 两个方法就只能是 Map 类型才能调用
    Bits() int        // 类型所占据的位数
    ChanDir() ChanDir // 返回通道的方向,只能是 chan 类型调用
    // 返回类型是否是可变参数,只能是 func 类型调用
    // 比如 t 是类型 func(x int, y ... float64)
    // 那么 t.IsVariadic() == true
    IsVariadic() bool
    Elem() Type // 返回内部子元素类型,只能由类型 Array, Chan, Map, Ptr, or Slice 调用

    // 返回结构体类型的第 i 个字段,只能是结构体类型调用
    // 如果 i 超过了总字段数,就会 panic
    Field(i int) StructField
    FieldByIndex(index []int) StructField        // 返回嵌套的结构体的字段
    FieldByName(name string) (StructField, bool) // 通过字段名称获取字段
    // FieldByNameFunc returns the struct field with a name
    // 返回名称符合 func 函数的字段
    FieldByNameFunc(match func(string) bool) (StructField, bool)
    In(i int) Type           // 获取函数类型的第 i 个参数的类型
    Key() Type               // 返回 map 的 key 类型,只能由类型 map 调用
    Len() int                // 返回 Array 的长度,只能由类型 Array 调用
    NumField() int           // 返回类型字段的数量,只能由类型 Struct 调用
    NumIn() int              // 返回函数类型的输入参数个数
    NumOut() int             // 返回函数类型的返回值个数
    Out(i int) Type          // 返回函数类型的第 i 个值的类型
    common() *rtype          // 返回类型结构体的相同部分
    uncommon() *uncommonType // 返回类型结构体的不同部分
}

3. Kind

  1. 使用Kind定义了内部所有类型,整数、布尔、字符串、map、slice、chan、struct等。
  2. 定义了每种Kind的字符串名称。
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
)

src\reflect\type.go
var kindNames = []string{
    Invalid:       "invalid",
    Bool:          "bool",
    Int:           "int",
    Int8:          "int8",
    Int16:         "int16",
    Int32:         "int32",
    Int64:         "int64",
    Uint:          "uint",
    Uint8:         "uint8",
    Uint16:        "uint16",
    Uint32:        "uint32",
    Uint64:        "uint64",
    Uintptr:       "uintptr",
    Float32:       "float32",
    Float64:       "float64",
    Complex64:     "complex64",
    Complex128:    "complex128",
    Array:         "array",
    Chan:          "chan",
    Func:          "func",
    Interface:     "interface",
    Map:           "map",
    Ptr:           "ptr",
    Slice:         "slice",
    String:        "string",
    Struct:        "struct",
    UnsafePointer: "unsafe.Pointer",
}


4. reflect.rtype == runtime._type

reflect定义了rtype,作为所有类型的通用部分。 与runtime中的_type结构一致。

// rtype must be kept in sync with ../runtime/type.go:/^type._type.

type tflag uint8
type nameOff int32
type typeOff int32
type textOff int32

type _type struct { //共48 字节
    size       uintptr  //8 字节
    ptrdata    uintptr  //8 字节 size of memory prefix holding all pointers
    hash       uint32   //4 字节
    tflag      tflag    //1 字节
    align      uint8    //1 字节  0x08 8字节对象
    fieldalign uint8    //1 字节  0x08 8字节对象 
    kind       uint8    //1 字节   0x14=20=RUNTIME_TYPE_KIND_INTERFACE
    alg        *typeAlg //8 字节
    // gcdata stores the GC type data for the garbage collector.
    // If the KindGCProg bit is set in kind, gcdata is a GC program.
    // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
    gcdata    *byte     //8
    str       nameOff   //4
    ptrToThis typeOff   //4
}

4.1 chantype


type chantype struct {
    typ  _type
    elem *_type
    dir  uintptr
}

4.2 maptype

type maptype struct {
    typ        _type
    key        *_type
    elem       *_type
    bucket     *_type // internal type representing a hash bucket
    keysize    uint8  // size of key slot
    valuesize  uint8  // size of value slot
    bucketsize uint16 // size of bucket
    flags      uint32
}

4.3 arraytype

type arraytype struct {
    typ   _type
    elem  *_type
    slice *_type
    len   uintptr
}

4.4 slicetype

type slicetype struct {
    typ  _type
    elem *_type
}

4.5 functype

type functype struct {
    typ      _type
    inCount  uint16
    outCount uint16
}

4.6 interfacetype

type interfacetype struct {
    typ     _type
    pkgpath name
    mhdr    []imethod
}

4.7 ptrtype


type ptrtype struct {
    typ  _type
    elem *_type
}

4.8 structtype


type structfield struct {
    name       name
    typ        *_type
    offsetAnon uintptr
}

type structtype struct {
    typ     _type
    pkgPath name
    fields  []structfield
}

// Method on non-interface type
type method struct {
    name nameOff // name of method
    mtyp typeOff // method type (without receiver)
    ifn  textOff // fn used in interface call (one-word receiver)
    tfn  textOff // fn used for normal method call
}


type imethod struct {
    name nameOff
    ityp typeOff
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容