数组作为常见的数据结构,作为一组相同元素类型的集合,数组是一块固定大小的连续的内存空间。
结构体
type Array struct {
Elem *Type //元素类型 element type
Bound int64 //元素的个数 number of elements; <0 if unknown yet
}
初始化
数组的初始化方式主要有两种,一种是定义指定大小的数值,第二种则是通过go的语法糖[…]
[3]int{1,2,3}
[...]int{1,2,3}
第二种通过[…]初始化的方式,会在编译期间调用cmd/compile/internal/gc.typecheckcomplit自动计算出数组的长度。
func typecheckcomplit(n *Node) (res *Node) {
.....
if n.Right.Op == OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ODDD {
n.Right.Right = typecheck(n.Right.Right, ctxType)
if n.Right.Right.Type == nil {
n.Type = nil
return n
}
//元素的类型
elemType := n.Right.Right.Type
//计算出元素的个数
length := typecheckarraylit(elemType, -1, n.List.Slice(), "array literal")
n.Op = OARRAYLIT
//调用NewArray完成初始化
n.Type = types.NewArray(elemType, length)
n.Right = nil
return n
}
.....
}
上面两种初始化过程,在go编译期间,最终都会调用NewArray来完成,并且一开始就确定该数组是会被分配在堆上还是在栈上,数组的初始化源代码在cmd/compile/internal/types.NewArray
func NewArray(elem *Type, bound int64) *Type {
if bound < 0 {
Fatalf("NewArray: invalid bound %v", bound)
}
t := New(TARRAY)
t.Extra = &Array{Elem: elem, Bound: bound}
t.SetNotInHeap(elem.NotInHeap())
return t
}
更多欢迎关注go成神之路