# Array Types

Arrays either have a `fixed size` or are `variably sized`, i.e., elements can be added and removed.

Fixed-size arrays have the form `[T; N]`, where `T` is the element type, and `N` is the size of the array. `N` has to be statically known, meaning that it needs to be an integer literal. For example, a fixed-size array of 3 `Int8` elements has the type `[Int8; 3]`.

Variable-size arrays have the form `[T]`, where `T` is the element type. For example, the type `[Int16]` specifies a variable-size array of elements that have type `Int16`.

It is important to understand that arrays are value types and are only ever copied when used as an initial value for a constant or variable, when assigning to a variable, when used as function argument, or when returned from a function call.

```
let size = 2
// Invalid: Array-size must be an integer literal
let numbers: [Int; size] = []

// Declare a fixed-sized array of integers
// which always contains exactly two elements.
//
let array: [Int8; 2] = [1, 2]

// Declare a fixed-sized array of fixed-sized arrays of integers.
// The inner arrays always contain exactly three elements,
// the outer array always contains two elements.
//
let arrays: [[Int16; 3]; 2] = [
    [1, 2, 3],
    [4, 5, 6]
]

// Declare a variable length array of integers
var variableLengthArray: [Int] = []
```

Array types are covariant in their element types. For example, `[Int]` is a subtype of `[AnyStruct]`. This is safe because arrays are value types and not reference types.
