复合数据类型

复合数据类型

_type 结构体

_type 是 go 里面所有类型的一个抽象,里面包含了类型的大小,哈希,对齐以及 k 类型编号等信息
Go 语言各种数据类型都是在 _type 字段的基础上,增加一些额外的字段来进行管理的

type _type struct {
	size       uintptr // 类型大小
  ptrdata    uintptr // 前缀持有所有指针的内存大小
  hash       uint32  // 类型的hash值
  tflag      tflag   // 信息标志,和反射相关
  align      uint8   // 类型在内存中的对齐方式
  fieldAlign uint8   // 结构体字段的对齐方式
	kind       uint8   // 类型的编号,有bool, slice, struct 等等等等
	
	equal func(unsafe.Pointer, unsafe.Pointer) bool // 类型的比较函数
	
	// gc 相关
	gcdata    *byte     // 一个指向GC数据的指针
	str       nameOff   // 类型名称在字符串表中的偏移量
	ptrToThis typeOff   // 指向该类型的指针在类型表中的偏移量
}
type interfacetype struct {
	typ     _type
	pkgpath name
	mhdr    []imethod
}

type maptype struct {
	typ    _type
	key    *_type
	elem   *_type
	bucket *_type // internal type representing a hash bucket
	// function for hashing keys (ptr to key, seed) -> hash
	hasher     func(unsafe.Pointer, uintptr) uintptr
	keysize    uint8  // size of key slot
	elemsize   uint8  // size of elem slot
	bucketsize uint16 // size of bucket
	flags      uint32
}

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

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

type slicetype struct {
	typ  _type
	elem *_type
}

type functype struct {
	typ      _type
	inCount  uint16
	outCount uint16
}

type ptrtype struct {
	typ  _type
	elem *_type
}

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

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

Slice

Map

String

Strings, bytes, runes and characters in Go

String 类型对应一个 struct
该 struct 包含两个元素,第一个是指向该 string 的字节数组的指针,第二个是 string 的长度,每个元素占 8 个字节

type StringHeader struct {
    Data uintptr // 指向字节数组的指针
    Len  int     // string的长度
}
byte 的相互拷贝

string 和 []byte 类型互转通常都通过内存拷贝的形式完成
但在例如 string(bytes) == "content" 等临时转换而非赋值的情况下,不发生内存拷贝,而是生成一个临时 string,其内指针指向字符数组

声明

str1 := "Hello World"
str2 := `Hello
Golang`

反引号声明的 string 中的特殊字符不需转义,所见即所得

Struct

// 使用new初始化
st := new(structName)
// 键值对初始化
st := structName{
  args1: value1,
  args2: value2,
  ...
}  
// 值列表初始化
st := stuctName{
  value1,
  value2,
  ...
}

无论 struct 指针还是 struct 变量,访问 struct 成员都使用 a.arg,实际上 Go 语言内部编译器将指针 a 转换为 *a

嵌套

第十八章 Struct 结构体 · Go 语言 42 章经 (gitbooks.io)

Struct 中的字段可以不用给名称,这时称为匿名字段,匿名字段的名称强制和类型相同

通过在 struct 内加入匿名字段可以以隐式继承该字段的方法及属性

type A

func (a *A) methodA()

type B struct {
	A
}

B.methodA() // 编译器自动解释为B.A.methodA()

Empty struct

空结构体不占据内存空间,因此可以用于占位符节省资源

Go 空结构体 struct{} 的使用 | Go 语言高性能编程 | 极客兔兔 (geektutu.com)

Tag

Go 标签在结构体中使用,在结构体编译阶段,可以通过反射被获取。

Tag 本身是一个字符串,它是 以空格分隔的 key:value 对,

struet demo {
    demo int `k1:"v1" k2:"v2"`
}

在 Go 中,tag 有着方便 json 字符串以及常用框架解析的重要作用

type Student struct { 
    ID int `json:"-"` // 该字段不进行序列化 
    Class int `json:"class"` // 该字段与class对应
    Name string `json:"name,omitempy"` // 如果为类型零值或空值,序列化时忽略该字段
    Age int `json:"age,string"` // 指定类型,支持string、number、boolen 
}

1a2c-Interface

1a2d-Channel