Система типов
Программист может объявить типы следующих видов:
- объект
- структура
- объединение
- класс
- именованный кортеж
- символ
- тип-сумма
- флаги
Объект
type Buffer =
val type : BufferType
var object : VkBuffer
var size : u32
val offset : u64
val usage : BufferUsageFlags
У типа Buffer
пять полей, каждое из которых также является параметром конструктора.
type StorageBuffer =
inherit Buffer type = BufferType/Storage
offset = 0
let device : VkDevice
let memory : VkMemory
def discard =
vk/destroy_buffer device object null
vk/free_memory device memory null
Во время наследования мы передали значения полей type
и offset
, оставшиеся три поля становятся параметрами конструктора StorageBuffer
. К ним добавляются еще два параметра/поля device
и memory
.
Видимость let
привязок и функций ограничена текущим файлом.
type AttachmentFormat @data =
val format : VkFormat
val samples : SampleCountFlags
val usage : ImageUsageFlags
Равенство объектов с атрибутом data
определяется содержимым полей.
import collection/List@mrc
let list @owner = List.new
Модификатор @mrc
, расшифровывается как manual reference counting, даёт доступ к версии типа без автоматического подсчета ссылок. Атрибут @owner
гарантирует освобождение памяти перед выходом из содержащей привязку функции, также доступен для полей объектов.
Ключевое слово new
используется для типов без параметров конструктора.
type Stack =
var align_h @mut = AlignH/Stretch
val items @mut = List<Control>.new
У типа List
есть изменяемая версия mut List
. Тип только для чтения нельзя снова преобразовать в изменяемый.
Без атрибута @mut
по окончании файла привязка align_h
превратится в только для чтения, а items
получит тип List<Control>
вместо mut List<Control>
.
type Slice<T> @byval =
val ptr : Ptr<T>
val size : u32
Объекты передаются по значению, если задан атрибут @byval
.
Поддерживается множественное наследование, но каждый тип может быть унаследован только один раз.
Структура
type ClearDepthStencilValue = struct
depth : f32
stencil : u32
Может наследовать другие структуры.
Объединение
type ClearValue = union
color : ClearColorValue
depth_stencil : ClearDepthStencilValue
Все поля указывают на один и тот же адрес в памяти. При инициализации нужно задать значение одного поля.
Класс
type Compare = class
def compare (other : Self) : Ordering
def (>) (rhs : Self) =
let result = compare rhs
result == Ordering/Greater
...
type TextPos = struct
line : u32
char : u32
def compare (other : TextPos) = when
line < other.line -> Ordering/Less
line > other.line -> Ordering/Greater
char < other.char -> Ordering/Less
char > other.char -> Ordering/Greater
else -> Ordering/Equal
is Compare
Тип может быть объявлен принадлежащим к классу, если соответствует всем заданным для класса ограничениям.
Именованный кортеж
type CString = ptr CChar
Чаще всего имеет только один элемент.
Символ
Также известен как единичный тип. По сути, является именованным кортежем с нулём элементов.
type None = symbol
Используется в типах-суммах.
Тип-сумма
Отличается от объединения наличием информации об активном поле.
type BufferType =
| Vertex
| Index
| Storage
| Image
| Uniform
Перечисление это тип-сумма единичных типов.
type Target =
| Buffer VkBuffer
| Image image : VkImage
width : u32
height : u32
Target/Buffer
это именованный кортеж, Target/Image
— структура.
type Option<T> =
| None
| Some T
type Result<T, E> =
| Ok T
| Error E
Option
позволяет представить отсутствие значения. Функция возвращает Result
, чтобы передать информацию об ошибке в случае неудачи.
type Metal @open = enum
Iron | Copper | Nickel
type Metal
Silver | Gold
type Platinum = symbol
inherit Metal
К открытым типам-суммам поля можно добавлять в любой точке кода. Модификатор enum
ограничивает типы полей единичными.
Флаги
type QueueFlags = flags
| Graphics
| Compute
| Transfer
| SparseBinding
| Protected
let queue_flags = QueueFlags/Graphics | QueueFlags/Transfer
assert queue_flags.contains QueueFlags/Graphics