Golang value part
https://go101.org/article/value-part.html
部分内容摘要
go中两大类型分类
go可以被视为C家庭语言,go和c语言在struct和指针类型的内存结构上有很多的相似之处。
另一方面,go也被视为c语言框架的。主要反映在,go支持的类型中有几种是内存结构不透明的,而c语言的内存结构是透明的。每个c值在内存中被封装到一个内存块中。而go有几种类型会存在多个内存块中。
go类型分为两大类:
只存放在一个内存块中的类型 | 存放在多个内存块中的类型 |
---|---|
solo Direct value part(直接指向值部分) | direct part->underlying part(还引用到底层下部分) |
boolean types | slice types |
numeric types | map types |
pointer types | channel types |
unsafe pointer types | function types |
struct types | interface types |
array types | string types |
注意:
- 接口和string的值是否包含底层部分(underlying parts)是由编译器决定的。标准go编译器是包含的。
- 函数值是否可能包含基础部分几乎很难甚至无法证明。go 101里视函数可能包含underlying parts的。
第二类中的类型种类通过封装许多实现细节为Go编程带来了很多便利。
go中的两种指针类型
type-safe pointer types和 type-unsafe pointer types。 包unsafe里有unsafe.Pointer类型,与c语言中void*相似。下面文中提到指针包含这两种指针。
指针指向另外一个值的地址,除非它是nil指针。我们说指针引用了这个值,或这个值被这个指针引用。值可以被隐式引用。
- 如果结构值a中有个指针字段b它引用了一个值c,我们可以说a也引用了c。
- x引用了y,y又引用了z,我们说x间接引用了z。不管x->y,y->z是直接还是间接引用。
引用关系是可以传递的。
第二类类型的可能内部定义
为了更好了解,可以假想第二分类类型是由第一分类类型实现。
内部关于map, channel, function类型的定义类似如下:
// map types
type _map *hashtableImpl
// channel types
type _channel *channelImpl
// function types
type _function *functionImpl
slice的实现可能如下 :
type _slice struct {
// referencing underlying elements
elements unsafe.Pointer
// number of elements and capacity
len, cap int
}
string如下 :
type _string struct {
elements *byte // referencing underlying bytes
len int // number of bytes
}
普通的interface
type _interface struct {
dynamicType *_type // the dynamic type
dynamicValue unsafe.Pointer // the dynamic value
}
标准go编译器的non-blank interface
type _interface struct {
dynamicTypeInfo *struct {
dynamicType *_type // the dynamic type
methods []*_function // method table
}
dynamicValue unsafe.Pointer // the dynamic value
}
Underlying Value Parts在赋值中不会被拷贝
现在我们了解到,第二类中类型的内部定义是指针持有者(指针或指针包装器)类型。知道这一点对理解Go中的价值复制行为非常有帮助。
在Go中,在目标值和源值具有相同的类型下,每个值的赋值(包括参数传递等)都是浅拷贝( shallow value copy)(如果它们的类型不同,我们可以认为在执行该赋值之前,源值将隐式转换为目标类型)。也就是说,源值中只有直接部分被拷贝到目标值中。如果源值中包含underlying value parts,然后目标值和源值的直接部分都引用了同样的underlying value part(s),它们是共享同样的underlying value part(s)。