Массив (Array из libretto/num)
В библиотеке libretto/num реализована поддержка массивов (изменяемая нумерованная последовательная коллекция фиксированной длины).
Длина массива зафиксирована при создании. Невозможно изменить длину уже созданного массива, нужно создать новый, куда скопировать содержимое старого массива.
Массив является изменяемым. Можно заменить элемент с указанным индексом на другой.
Массивы не рекомендуется к обычному использованию, только для целей оптимизации.
Массив задаётся трейтом Array из пакета libretto/num. Запись определения Array, который типизируется типом элемента массива:
trait Array[A] {
def `!`(position: Int): A
def set(position: Int, newValue: A): ()
def len: Int
}
Метод ! для доступа к элементу массива по индексу (от 0 включительно). В случае выхода за границы будет исключение.
Метод set для установки элемента массива по индексу (от 0 включительно). В случае выхода за границы будет исключение.
Метод len для получения длины массива (фиксированное значение).
Можно создать массив из последовательности при помощи метода array из пакета libretto/num: def array[A](seq: A): Array[TypeSingle[A]] (запись условная)
Пример:
use libretto/num
def main = {
fix arr = (10,20,30).*num/array
println: type(arr)
println: arr.len
0..(arr.len - 1) as i.${
println: s"#{i}: #{arr.!(i)}"
}
arr.set(0): 100
arr.set(1): 101
arr.set(2): 103
0..(arr.len - 1) as i.${
println: s"#{i}: #{arr.!(i)}"
}
}
Выдает:
libretto/num/Array[libretto/Int]
3
0: 10
1: 20
2: 30
0: 100
1: 101
2: 103
Другой способ создания при помощи метода newArray (запись условная!):
def newArray[A](len: Int, fillValue: ByName[A]): Array[A]
Указывается длина создаваемого массива и выражение (заполнитель), которое вызывается для каждого элемента последовательно при инициализации массива.
В массиве можно хранить пустоту и даже последовательности.
Пример:
use libretto/num
def main = {
fix arr = num/newArray[Any*](10, ())
println: type(arr)
println: arr.len
println: arr.!(0)
arr.set(0): (1, 2, 3)
println: arr.!(0)
}
Выдает:
libretto/num/Array[libretto/Any*]
10
()
(1,2,3)
Пример динамического заполнителя:
use libretto/num
def main = {
var v = 0
fix arr = num/newArray[Int](10): v.${ v = v + 100 }
0..(arr.len - 1) as i.${
println: s"#{i}: #{arr.!(i)}"
}
}
Выдает:
0: 0
1: 100
2: 200
3: 300
4: 400
5: 500
6: 600
7: 700
8: 800
9: 900
Вызов newArray можно не типизировать типом элемента. В этом случае типом элементов массива будет тип результата выражения-заполнителя.
Массивы можно делать многомерными. Пример:
use libretto/num
def main = {
fix arr = num/newArray(3, num/newArray(5, 0))
0..2 as a.${
0..4 as b.${ print: " "+arr.!(a).!(b) }
println()
}
0..2 as v.${ arr.!(v).set(v): (v + 1) }
println()
0..2 as a.${
0..4 as b.${ print: " "+arr.!(a).!(b) }
println()
}
}
Выдает:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 3 0 0