# Built-in Types

Every value in Sway is of a certain type. Although deep down, all values are just ones and zeroes in the underlying virtual machine, Sway needs to know what those ones and zeroes actually mean. This is accomplished with _types_.

<!-- This section should explain how Sway types are inferred -->
<!-- sway_types:example:start -->
Sway is a statically typed language. At compile time, the types of every value must be known. This does not mean you need to specify every single type: usually, the type can be reasonably inferred by the compiler.
<!-- sway_types:example:end -->

## Primitive Types

<!-- This section should list the primitive types in Sway -->
<!-- prim_types:example:start -->
Sway has the following primitive types:

1. `()` (unit type)
1. `u8` (8-bit unsigned integer)
1. `u16` (16-bit unsigned integer)
1. `u32` (32-bit unsigned integer)
1. `u64` (64-bit unsigned integer)
1. `u256` (256-bit unsigned integer)
1. `str[]` (fixed-length string)
1. `str` (string slices)
1. `bool` (Boolean `true` or `false`)
1. `b256` (256 bits (32 bytes), i.e. a hash)

All other types in Sway are built up of these primitive types, or references to these primitive types. You may notice that there are no signed integers&mdash;this is by design. In the blockchain domain that Sway occupies, floating-point values and negative numbers have smaller utility, so their implementation has been left up to libraries for specific use cases.
<!-- prim_types:example:end -->

## Unit Type

The unit type, `()`, is a type that allows only one value, and thus, represents a value with no information. It is used to indicate the absence of a meaningful value, or the result of a function that performs an action, but does not return any data. The value of the unit type, called simply unit, has the same symbol as the unit type, `()`. Unit type in Sway serves a similar purpose as `void` in imperative languages like C or Java.

For example:

```Sway
fn returns_unit() -> () { // Here, `()` represent the unit type.
    ()                    // Here, `()` represents the single unit value of the unit type.
}
```

In Sway, if the function return type is not specified, it is `()` by default. Thus, the above example is semantically same as the following:

```Sway
fn returns_unit() {
}
```

## Numeric Types

All of the unsigned integer types are numeric types.

Numbers can be declared with binary syntax, hexadecimal syntax, base-10 syntax, and underscores for delineation. Let's take a look at the following valid numeric primitives:

```sway
0xffffff    // hexadecimal
0b10101010  // binary
10          // base-10
100_000     // underscore delineated base-10
0x1111_0000 // underscore delineated binary
0xfff_aaa   // underscore delineated hexadecimal
```

<!-- This section should explain the default numeric type in Sway -->
<!-- default_num:example:start -->
The default numeric type is `u64`. The FuelVM's word size is 64 bits, and the cases where using a smaller numeric type saves space are minimal.

If a 64-bit or 256-bit arithmetic operation produces an overflow or an underflow,
computation gets reverted automatically by FuelVM.

8/16/32-bit arithmetic operations are emulated using their 64-bit analogues with
additional overflow/underflow checks inserted, which generally results in
somewhat higher gas consumption.

The same does not happen with 256-bit operations, including `b256`, which uses specialized operations and are as efficient as possible.
<!-- default_num:example:end -->

## Boolean Type

<!-- This section should explain the `bool` type -->
<!-- bool:example:start -->
The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`.
<!-- bool:example:end -->

For example:

```sway
fn returns_false() -> bool {
    let boolean_value: bool = true;
    !boolean_value
}
```

## String Slices

<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, string literals are stored as variable length string slices. Which means that they are stored as a pointer to the actual string data and its length.
<!-- str:example:end -->

```sway
let my_string: str = "fuel";
```

String slices, because they contain pointers have limited usage. They cannot be used as constants, storage fields, or configurable constants, nor as main function arguments or returns.

For these cases one must use string arrays, as described below.

## String Arrays

<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, static-length strings are a primitive type. This means that when you declare a string array, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets.
<!-- str:example:end -->

Let's take a look:

```sway
let my_string: str[4] = __to_str_array("fuel");
```

Because the string literal `"fuel"` is four letters, the type is `str[4]`, denoting a static length of 4 characters. Strings default to UTF-8 in Sway.

As above, string literals are typed as string slices. So that is why the need for `__to_str_array` that convert them to string arrays at compile time.

Conversion during runtime can be done with `from_str_array` and `try_as_str_array`. The latter can fail, given that the specified string array must be big enough for the string slice content.

```sway
let a: str = "abcd";
let b: str[4] = a.try_as_str_array().unwrap();
let c: str = from_str_array(b);
```

## Compound Types

_Compound types_ are types that group multiple values into one type. In Sway, we have arrays and tuples.

## Tuple Types

<!-- This section should explain what a tuple is -->
<!-- tuple:example:start -->
A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type.
<!-- tuple:example:end -->

Let's take a look at some examples.

```sway
let x: (u64, u64) = (0, 0);
```

This is a tuple, denoted by parenthesized, comma-separated values. Note that the type annotation, `(u64, u64)`, is similar in syntax to the expression which instantiates that type, `(0, 0)`.

```sway
let x: (u64, bool) = (42, true);
assert(x.1);
```

In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`.

<!-- This section should explain how to access a value in a tuple -->
<!-- tuple_val:example:start -->
To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring.
<!-- tuple_val:example:end -->

```sway
struct Foo {}
let x: (u64, Foo, bool) = (42, Foo {}, true);
let (number, foo, boolean) = x;
```

To create one-arity tuples, we will need to add a trailing comma:

```sway
let x: u64 = (42);     // x is of type u64
let y: (u64) = (42);   // y is of type u64
let z: (u64,) = (42,); // z is of type (u64), i.e. a one-arity tuple
let w: (u64) = (42,);  // type error
```

## Arrays

<!-- This section should explain what an array is -->
<!-- array:example:start -->
An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types including non-primitive types.
<!-- array:example:end -->

An array is written as a comma-separated list inside square brackets:

```sway
let x = [1, 2, 3, 4, 5];
```

<!-- This section should explain arrays in depth -->
<!-- array_details:example:start -->
Arrays are allocated on the stack since their size is known. An array's size is _always_ static, i.e. it cannot change. An array of five elements cannot become an array of six elements.

Arrays can be iterated over, unlike tuples. An array's type is written as the type the array contains followed by the number of elements, semicolon-separated and within square brackets, e.g., `[u64; 5]`. To access an element in an array, use the _array indexing syntax_, i.e. square brackets.
<!-- array_details:example:end -->

Array elements can also be mutated if the underlying array is declared as mutable:

```sway
let mut x = [1, 2, 3, 4, 5];
x[0] = 0;
```

```sway
script;

struct Foo {
    f1: u32,
    f2: b256,
}

fn main() {
    // Array of integers with type ascription
    let array_of_integers: [u8; 5] = [1, 2, 3, 4, 5];

    // Array of strings
    let array_of_strings = ["Bob", "Jan", "Ron"];

    // Array of structs
    let array_of_structs: [Foo; 2] = [
        Foo {
            f1: 11,
            f2: 0x1111111111111111111111111111111111111111111111111111111111111111,
        },
        Foo {
            f1: 22,
            f2: 0x2222222222222222222222222222222222222222222222222222222222222222,
        },
    ];

    // Accessing an element of an array
    let mut array_of_bools: [bool; 2] = [true, false];
    assert(array_of_bools[0]);

    // Mutating the element of an array
    array_of_bools[1] = true;
    assert(array_of_bools[1]);
}

```
