Maps

TBD.

Also known as Associative Arrays, or Objects in other languages.

All maps must have a definition, which define their fields and datatypes. There can also be anonymous maps, which may contain any key.

Named Maps


// Here we define a map, called Person
  ╰╴No statement matched
map Person { String name, String surname, Int age, } // Here we declare an instance of a Person. val john_doe = Person { name: "John", surname: "Doe", age: 33, } // If the compiler can infer the type of a Map, // we can omit its type var Person mary_jane = .{ name: "Mary", surname: "Jane", age: 27, }
thp

To access the fields of a map we use square braces [].


mary_jane["age"] += 1
╰╴No statement matched
print(mary_jane["name"]) // Mary
thp

Or dot access . if the field’s name is a valid identifier.


mary_jane.age += 1
╰╴No statement matched
print(mary_jane.name)
thp

Anonymous maps

An anonymous map allows us to store and retrieve any key of any datatype. They are declared as Map.


val car = Map {
╰╴No statement matched
brand: "Toyota", model: "Corolla", year: 2012, }
thp

Anonymous maps can also can have their type omitted.


var car = .{
          ╰╴Invalid variable declaration
brand: "Toyota", model: "Corolla", year: 2012, }
thp

If the compiler encounters a map without a type (that is, .{}) and doesn’t expect a specific type, it will assume it is an anonymous map.

We can freely assign fields to an anonymous map:


// Modify an existing field
  ╰╴No statement matched
car["year"] = 2015 // Create a new field car["status"] = "used"
thp

However, if we try to access a field of an anonymous map we’ll get a nullable type, and we must annotate it.


// This is ok, we are declaring what datatype we expect
  ╰╴No statement matched
String? car_status = car["status"] // This won't work, the compiler doesn't know what datatype to use var car_status = car["status"]
thp

Instead, we can use the get function of the map, which expects a datatype and returns that type as nullable


val car_status = car.get[String]("status")
╰╴No statement matched
thp

Both ways to get a value will check that the key exists in the map, and that it has the correct datatype. If either the key doesn’t exist or it has a different datatype, it will return null.

We can also use dynamic keys, following the same rules:


val generated_value = "key"
╰╴No statement matched
String? v = map[generated_value] // or val v = map[String](generated_value)
thp