边界检查

    @boundscheck(...) 把代码块标记为要执行边界检查。但当这些代码块被被宏 @inbounds(...) 标记的代码包裹时,它们可能会被编译器移除。仅当@boundscheck(...) 代码块被调用函数包裹时,编译器会移除它们。比如你可能这样写的 sum 方法:

    使用自定义的类数组类型 MyArray,我们有:

    getindexsum 包裹时,对 checkbounds(A,i) 的调用会被忽略。如果存在多层包裹,最多只有一个 @boundscheck 被忽略。这个规则用来防止将来代码被改变时潜在的多余忽略。

    There may be certain scenarios where for code-organization reasons you want more than one layer between the @inbounds and @boundscheck declarations. For instance, the default getindex methods have the chain calls getindex(IndexStyle(A), A, i) calls _getindex(::IndexLinear, A, i).

    The overall hierarchy is:

    checkbounds(A, I...) throws an error if the indices are invalid, whereas checkbounds(Bool, A, I...) returns in that circumstance. checkbounds_indices discards any information about the array other than its axes tuple, and performs a pure indices-vs-indices comparison: this allows relatively few compiled methods to serve a huge variety of array types. Indices are specified as tuples, and are usually compared in a 1-1 fashion with individual dimensions handled by calling another important function, checkindex: typically,

    so checkindex checks a single dimension. All of these functions, including the unexported checkbounds_indices have docstrings accessible with ? .

    If you have to customize bounds checking for a specific array type, you should specialize checkbounds(Bool, A, I...). However, in most cases you should be able to rely on checkbounds_indices as long as you supply useful axes for your array type.

    If you have novel index types, first consider specializing checkindex, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type (similar to CartesianIndex), then you may have to consider specializing checkbounds_indices.