Стандартная библиотека и среда

Базовая библиотека

Сначала используйте повседневные функции, а к ограниченным двоичным операциям и кодекам переходите только при необходимости.

Базовая библиотека решает задачи, встречающиеся в большинстве небольших программ: вывод текста, преобразование значений, работа с Unicode, представление отсутствия и ошибки, преобразование коллекций. Начинайте с неё, прежде чем искать специализированное пространство имён.

Выберите повседневную функцию

ЗадачаЧто использоватьРезультат
Вывести одну строкуprint("text")()
Разобрать целое число из текстаtoInt(text)Option<int>
Разобрать число с основанием от 2 до 36toIntRadix(text, radix)Option<int>
Преобразовать int в floattoFloat(value)float
Получить скаляр Unicode из кодовой точкиfromCodePoint(value)Option<string>
Разобрать строку на скаляры Unicodetext.scalars()Array<string>
Преобразовать, отобрать или свернуть элементыmap, filter, reduceНовое значение

Some, None, Ok и Err — конструкторы прелюдии. Для None, Ok, Err или пустой коллекции нужен ожидаемый тип, если вывод типов не может определить все параметры.

Разберите и преобразуйте значения

Программа сохраняет неудачный разбор как None и считает корейский текст по скалярам Unicode, а не по байтам.

TOPAZ
function parseAll(values: Array<string>) -> Array<Option<int>> {
    return map(values, value => toInt(value))
}

let scalars = "토파즈".scalars()
let parsed = parseAll(["1", "x", "3"])
print("{scalars.length}:{parsed}")
Вывод
3:[Some(1), None, Some(3)]

print принимает строку, поэтому результат показан через интерполяцию. toInt возвращает None для "x", а map не превращает обычное отсутствие в ошибку выполнения. Если вызывающему коду нужна причина, преобразуйте отсутствие в содержательный Result с помощью match.

Частая ошибка: toFloat преобразует int, а не разбирает строку. Свободных универсальных функций toString, len, println и type_of нет. Используйте интерполяцию, точный метод типа наподобие .length и документированные функции преобразования.

Публичная поверхность

Для повседневных задач используйте следующие точные имена:

  • print(string) -> () выводит строку. При каждом вызове input() -> string возвращает одной строкой весь текст, предоставленный средой для данного запуска; это не построчное чтение.
  • toInt(string) -> Option<int> и toIntRadix(string, int) -> Option<int> разбирают целые числа.
  • toFloat(int) -> float преобразует целое число, а не разбирает текст.
  • fromCodePoint(int) -> Option<string> создаёт один допустимый скаляр Unicode.
  • text.scalars() -> Array<string> представляет строку как скаляры Unicode.
  • Some и None создают Option, а Ok и ErrResult.
  • option.okOr(error: E) -> Result<T, E> вычисляет ошибку заранее. option.okOrElse(f: () -> E) -> Result<T, E> вызывает f только для None.
  • option.map(f: (T) -> U) -> Option<U> преобразует значение Some, а option.flatMap(f: (T) -> Option<U>) -> Option<U> не добавляет ещё один слой Option. Для None обе функции пропускают вызов f.
  • result.map(f: (T) -> U) -> Result<U, E> преобразует значение Ok, а result.flatMap(f: (T) -> Result<U, E>) -> Result<U, E> не добавляет ещё один слой Result. Для Err обе функции пропускают вызов f.
  • Свободные функции map, filter и reduce преобразуют перебираемые значения и отличаются от перечисленных методов значений. Ни одна из этих функций не перехватывает ошибку выполнения.

Разделы Bytes, ByteBuffer, Hash и Codec ниже показывают выбранную ограниченную поверхность, а не полный перечень. Опирайтесь только на явно показанные там члены. Похожая внутренняя функция отдельной среды выполнения или целевой платформы не становится дополнительным API Топаза.

Соберите байты на месте

Если алгоритм многократно записывает данные в одно непрерывное значение фиксированной длины, используйте ByteBuffer.allocate(length, value = 0). Для set, fill и copy корневая привязка должна быть let mut. Все диапазоны и значения байтов проверяются до первой записи, поэтому ошибка выполнения не оставляет цель частично изменённой.

TOPAZ
let mut row = ByteBuffer.allocate(8)
row.fill(0, 8, 255)
row.set(0, 137)

let mut frame = ByteBuffer.allocate(12)
frame.copy(row, 0, 2, 8)
let payload = frame.toBytes()
print(payload.toHex())
Вывод
000089ffffffffffffff0000

Присваивание ByteBuffer разделяет одну изменяемую сущность. ByteBuffer.fromBytes копирует в новый буфер, а toBytes() создаёт неизменяемый снимок. Сам ByteBuffer нельзя передавать через Web export, сравнивать, использовать как ключ Map/Set, включать в текст или JSON.

Вычислите поле целостности CRC-32

Hash.crc32(data) возвращает беззнаковое значение CRC-32/ISO-HDLC. Оно подходит для полей целостности формата, но не для аутентификации или защиты от преднамеренной подмены.

TOPAZ
let checksum = Hash.crc32(Bytes.encodeUtf8("123456789"))
print("{checksum}")
Вывод
3421780262

Та же операция доступна как std.hash.crc32 в фиксированной поверхности стандартных модулей.

Создайте детерминированный fixed DEFLATE

Для одного канонического raw-блока DEFLATE с фиксированным Хаффманом без обрамления zlib или gzip используйте Codec.deflateFixedCompress(bytes).

TOPAZ
match Codec.deflateFixedCompress(Bytes.encodeUtf8("hello")) {
  case Ok(compressed) => print(compressed.toHex())
  case Err(error) => print(error)
}
Вывод
cb48cdc9c90700

Поиск и память ограничены, ввод свыше 256 MiB возвращает Err. В генерации Python этого члена Codec нет, поэтому цель отклоняется до записи артефакта.

Создайте детерминированный fixed zlib

Если формату нужен полный поток zlib, используйте Codec.zlibFixedCompress(bytes). Он содержит фиксированный заголовок 78 01, данные с фиксированным Хаффманом и трейлер Adler-32.

TOPAZ
match Codec.zlibFixedCompress(Bytes.encodeUtf8("hello")) {
  case Ok(compressed) => print(compressed.toHex())
  case Err(error) => print(error)
}
Вывод
7801cb48cdc9c90700062c0215

Ввод свыше 256 MiB возвращает Err. В генерации Python этого члена Codec нет, поэтому цель отклоняется до создания артефакта. Операция не добавляет распаковку, уровни, словари, потоковую обработку или общий API Adler-32.

Добавьте защитные байты Reed–Solomon

Codec.reedSolomon255223Protect(bytes) создаёт систематические кодовые слова RS(255,223). За каждыми 223 байтами данных следуют 32 байта чётности, а последний блок данных дополняется нулями.

TOPAZ
match Codec.reedSolomon255223Protect(Bytes.encodeUtf8("hello")) {
  case Ok(protected) => print("{protected.length()}")
  case Err(error) => print(error)
}
Вывод
255

Исходную логическую длину хранит вызывающий код. Ввод не может быть пустым и ограничен 65 535 блоками. Функция создаёт защитные байты, но не обнаруживает и не исправляет повреждение. В генерации Python этого члена Codec нет, поэтому цель отклоняется до создания артефакта.

Точные границы

  • Строковые операции используют позиции скаляров, если в названии явно не указаны байты.
  • Option.map сохраняет обычное отсутствие, а Result.map не перехватывает ошибку выполнения.
  • map, filter и reduce принимают только фиксированные семейства перебираемых значений.
  • Типизированному JSON нужен один полностью известный записанный тип; ошибка данных содержит путь от $.
  • input и print требуют соответствующей возможности среды.
  • assert — функция только тестового профиля, а не ключевое слово языка.

Продолжите с обзора стандартной библиотеки, Null, Option, Result и ошибки или поведения среды выполнения.