Overview
Virgil has arrays built into the base language. An array is a collection
that maps an integer index to an element, a location that can
store a value. Arrays represent a contiguous region of memory cells
and come with the implicit guarantee that an access of an element is a constant time operation.
Virgil arrays are statically typed, so that every array has a type which is
written elem[]
where elem
is the type of the elements of the
array. Every Virgil array also has a length that is fixed when
the array is allocated; valid indices to an array a
are the interval
[0, a.length - 1]
(i.e. all indices between zero and the length of the
array, inclusive). Every access of an array is dynamically checked against the valid
indices for the array and will generate a BoundsCheckException
if the
index is not valid for the array.
Allocating Arrays
local x: int[] = { 0, 1, 2, 3 }; local y: int[] = new int[89];
Arrays can be allocated one of two ways in Virgil. The first way is to
declare an array literal, which is a list of
expressions enclosed in curly braces {
... }
.
Array literals can only be used in the initialization expression for
a local variable or field. When the statement that contains the array
literal is executed, a new array is allocated of the corresponding
length and its elements are initialized to the result of evaluating
each expression in the literal. The second way is to explicitly
allocate a new array using the new
operator. The type
of the array is given, and an expression that is evaluated and used
as the length of the array. All of the elements of the array are initialized
to the default value
for the element type (e.g. 0
for integers, null
for reference types).
Accessing Arrays
local x: int = array[expr]; array[expr] = x; local y: int = array.length;
Arrays can be accessed using the []
array subscript operator. The
expression representing the array is given, followed by the index in square
brackets [
... ]
. The index expression must
be of type of int
. Array index expressions can be used as the
target of an assignment statement, in which case, the value of the right
hand side is assigned to the specified element. The length of an array
can be accessed as if it were a field by applying the .length
suffix to the array reference.
Arrays are References
local x: int[] = new int[1]; local y: int[] = x; y[0] = 100; local z: int = x[0]; // z == 100
Virgil arrays are always passed by reference. This means that assigning a variable to an array expression, or passing an array across a method call does not copy the contents of the array, but instead just passes a reference to the array's contents. Thus, updates to the array's elements after a reference has been passed are visible to the new holder of the reference.
Exceptions
local x: int[] = null; local y: int = x[0]; // NullCheckException local z: int[] = new int[2]; local w: int = z[3]; // BoundsCheckException
Array accesses can generate two kinds of exceptions. Like any other
reference in Virgil, including object references and delegates, array references
may be null
, which indicates the reference does not point to
any valid array. An array length access or
array element access will generate a NullCheckException
if the array reference is null
. If the reference is not null
then the index value is checked against the valid bounds for the array. If the index
is out of the bounds of the array (i.e. it is less than zero or is greater than or
equal to the length of the array), a BoundsCheckException
will be generated.
Multi-dimension Arrays
local x: int[][] = { {0, 1}, {0, 4} }; local y: int[][] = new int[3][4]; local w: int[] = x[0]; local z: int = x[0][0];
Arrays can have multiple dimensions in Virgil. Such multi-dimensional arrays are represented as arrays of arrays. Array literal expressions allow nesting of multiple array literals; new expressions allow multiple dimensions to be specified. Accesses to multiple dimensional arrays are then straightforward; the left part of the expression represents the selection of which of the nested arrays to acccess, and the rightmost part specifies the element of that array to access.
Strings as Arrays of Characters
local x: char[] = "str"; local y: char[] = { 's', 't', 'r' };
Strings are represented as character arrays of fixed length in Virgil. The syntax for declaring string literals is in fact just a shorthand for writing out a character array literal.
Go back to the tutorial.