Sequences
Ki has two fundamental sequential data types:
- Array:
array
- Dynamic array:
dynarray
Arrays And Dynamic Arrays
Arrays and dynamic arrays are very similar. Both have:
- An element type
- An element count
The difference is that an array
's element count cannot be changed, whereas a
dynarray
's element not only can be changed, it will automatically resize as
elements are added to or removed from it.
fn main() {
# Initialize an array with 3 elements.
var fruits: array(["apple", "banana", "cherry"])
# Initialize a dynarray with 1 element; then add another.
var vegetables: dynarray(["asparagus"])
vegetables.append("broccoli")
# Initialize an array with 3 empty elements; then fill them.
var planets: array(@type: string, count: 3)
echo("Each element of planets is the empty string ({{planets[0]}}), see?")
planets[0] = "Mercury"
planets[1] = "Venus"
planets[2] = "Earth"
# planets contains pointers. If you want to reserve the memory, use
# constructors.
var planets2: array(string(length: 7), count: 3)
planets2[0] = "Mars"
planets2[1] = "Jupiter"
planets2[2] = "Saturn"
# Initialize a dynarray; reserve some space; then add some elements using
# indexing.
var trees: dynarray(type: <str>)
with (t!: trees.ensure_capacity(4)) {
t[0] = "oak"
t[1] = "maple"
t[2] = "pine"
t[3] = "maple"
}
}
Strings And Dynamic Strings
Strings and dynamic strings are fundamentally an array
(or dynarray
,
respectively) with the element type set to rune
. In addition to this, they
also provide a useful interface for string management. For more information,
see strings
Linked Lists
Ki provides a linked list simply called list
.
type Player {
var name: *"Player"
var health: 0
}
fn main() {
val players1: list(
type: *<Player>!
)
list.append(*Player("Player 1", 10)!)
val players2: list([
*Player(*"Player 1", 10)!,
*Player(*"Player 2", 10)!
])
}
Indexing
You have two options when indexing into a container. First, you can use
with
:
fn main() {
var names: dynarray(["Aaron", "Bathsheba", "Cain"])
var places: array(["Gomorrah", "Jerusalem", "Bethlehem"])
with (second_name: names[1]) {
echo("Second name: ${second_name}")
}
with (first_place: places[0]) {
echo("First place: ${first_place}")
}
}
Or, if the container isn't resizable, you can avoid a with
block:
fn main() {
range i: [0..2]
var names: array(["Aaron", "Bathsheba", "Cain"])
var places: array(["Gomorrah", "Jerusalem", "Bethlehem"])
echo("Second name: ${names[i(2)]}")
echo("First place: ${places[i(0)]})
}
This works because a value of type i
can only ever be 0, 1, or 2. Because
the sizes of names
and places
are fixed at 3, that means indices 0, 1 and 2
will always be valid.