Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数组的上限推导和越界检查 #37

Open
kevinyan815 opened this issue Dec 24, 2020 · 0 comments
Open

数组的上限推导和越界检查 #37

kevinyan815 opened this issue Dec 24, 2020 · 0 comments

Comments

@kevinyan815
Copy link
Owner

kevinyan815 commented Dec 24, 2020

什么是数组

数组是由相同类型元素的集合组成的数据结构,计算机会为数组分配一块连续的内存来保存其中的元素,我们可以利用数组中元素的索引快速访问特定元素。Go语言中我们会使用如下所示的方式来表示数组类型:

[10]int
[200]interface{}

Go语言数组在初始化之后大小就无法改变,存储元素类型相同、但是大小不同的数组类型在Go语言看来也是完全不同的,只有两个条件都相同才是同一类型。

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
}

编译期间的数组类型Array是由上述的 NewArray 函数生成的,该类型包含两个字段,分别是元素类型Elem和数组的大小Bound,这两个字段共同构成了数组类型,而当前数组是否应该在堆栈中初始化也在编译期就确定了。

初始化

数组在Go语言里有两种不同的创建方式,一种是显式的指定数组大小,另一种是使用 [...]T 声明数组,Go语言会在编译期间通过源代码推导数组的大小:

arr1 := [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3}

上述两种声明方式在运行期间得到的结果是完全相同的,后一种声明方式在编译期间就会被转换成前一种,这也就是编译器对数组大小的推导。

访问越界

无论是在栈上还是静态存储区,数组在内存中都是一连串的内存空间,如果我们不知道数组中元素的数量,访问时可能发生越界;

数组访问越界是非常严重的错误,Go语言可以在编译期间的静态类型检查阶段判断简单的数组越界:

  1. 访问数组的索引是非整数时,报错 “non-integer array index %v”;
  2. 访问数组的索引是负数时,报错 “invalid array index %v (index must be non-negative)";
  3. 访问数组的索引越界时,报错 “invalid array index %v (out of bounds for %d-element array)";

数组和字符串的一些简单越界错误都会在编译期间发现,例如:直接使用整数或者常量访问数组;但是如果使用变量去访问数组或者字符串时,编译器就无法提前发现错误,需要Go语言运行时阻止不合法的访问,比如:

// 编译错误
arr[4]: invalid array index 4 (out of bounds for 3-element array)
// 运行时错误
arr[i]: panic: runtime error: index out of range [4] with length 3

Go语言运行时在发现数组、切片和字符串的越界操作会由运行时的runtime.panicIndexruntime.goPanicIndex 触发程序的运行时错误并导致崩溃退出。

所有内容摘录自:https://draveness.me/golang/docs/part2-foundation/ch03-datastructure/golang-array/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant