Эта страница описывает Топаз v5.17. Прежде чем считать её актуальной, сверьте поле version в /version.json со значением 5.17.
Используйте модули, когда у одного файла есть чёткая задача, а другому файлу
нужен его результат. Каждый файл .tpz является отдельным модулем; особого
объявления module нет.
Соберите одну программу из двух файлов
Исходные файлы приложения учебного плана расположены так:
study-plan/
├── topaz.toml
├── topaz.lock
└── src/
├── main.tpz
└── plan.tpzsrc/plan.tpz отвечает за модель данных и повторно используемые операции:
export record УчебнаяЗадача {
название: string,
минуты: int,
выполнена: bool = false,
}
function разобратьМинуты(текст: string) -> Result<int, string> {
match toInt(текст) {
case Some(значение) if значение > 0 => Ok(значение)
case _ => Err("minutes must be a positive integer")
}
}
export function создатьЗадачу(
название: string,
текстМинут: string,
выполнена: bool = false,
) -> Result<УчебнаяЗадача, string> {
let минуты = разобратьМинуты(текстМинут)?
Ok(УчебнаяЗадача { название: название, минуты: минуты, выполнена: выполнена })
}
export function подвестиИтог(задачи: Array<УчебнаяЗадача>) -> string {
let mut осталось = 0
for задача in задачи {
if !задача.выполнена {
осталось = осталось + задача.минуты
}
}
"tasks={задачи.length}, remaining={осталось} minutes"
}src/main.tpz выбирает три нужных ему имени:
import src.plan { УчебнаяЗадача, создатьЗадачу, подвестиИтог }
export function main(аргументы: Array<string>, ввод: string) -> Result<int, string> {
let задачи: Array<УчебнаяЗадача> = [
создатьЗадачу("Run first program", "10", true)?,
создатьЗадачу("Build application", "25", false)?,
]
print(подвестиИтог(задачи))
Ok(0)
}Из корня пакета проверьте и запустите разрешённую единицу компиляции:
topaz check --root . --locked
topaz run --root . --locked
tasks=2, remaining=25 minutesПри явно заданном корне путь src.plan соответствует файлу
src/plan.tpz. Единица компиляции состоит из точки входа и всех модулей,
достижимых по цепочке импортов. Файлы вне этой цепочки для данной точки входа
не проверяются.
Экспортируйте только нужную границу
Имя остаётся закрытым, если перед его объявлением нет export.
УчебнаяЗадача, создатьЗадачу и подвестиИтог пересекают границу модуля, а
разобратьМинуты остаётся деталью реализации. Попытка выбрать или прочитать его
из src/main.tpz приводит к статической ошибке. Импортированные привязки
доступны только для чтения.
Выборочный импорт привязывает экспортированные имена напрямую:
| Задача | Каноническая форма |
|---|---|
| Выбрать несколько имён | import src.plan { УчебнаяЗадача, создатьЗадачу } |
| Переименовать выбранное имя | import src.plan { подвестиИтог as показатьИтог } |
| Привязать пространство имён | import src.plan as план |
При импорте пространства имён экспортированные значения доступны как
план.создатьЗадачу(...). Пространство имён служит для разрешения имён во время
компиляции и не является значением программы. Экспортированный тип
план.УчебнаяЗадача допустим в позиции типа, но запись
план.УчебнаяЗадача { ... } не создаёт значение. Для прямого создания именной
записи выберите УчебнаяЗадача отдельным импортом.
Исправление частой ошибки: формы нельзя объединить в
import src.plan as план { подвестиИтог }. Выберите либо импорт пространства
имён, либо выборочный импорт.
Корень, инициализация и пакет — разные решения
- Путь модуля — это разделённый точками адрес под выбранным корнем. Имена файлов и каталогов должны совпадать точно.
- Все импорты образуют пролог верхнего уровня и располагаются перед остальными элементами.
- Зависимый модуль инициализируется один раз до импортирующего его модуля. Импортируемый модуль может содержать объявления и привязки, но не свободные исполняемые инструкции верхнего уровня, например цикл или присваивание.
topaz.tomlзадаёт для инструментов имя пакета, точку входа, зависимости и цель сборки. Он не вводит ещё один синтаксис объявления модулей.
Как в примере выше, команда пакета может предоставить точку входа и корень.
Если файл указан напрямую, его каталог служит корнем по умолчанию; параметр
--root позволяет явно выбрать содержащий его корень.
Циклические импорты отклоняются
Предположим, a.tpz импортирует b.tpz:
import b
export function изА() -> int {
1
}а b.tpz импортирует a.tpz:
import a
export function изБ() -> int {
2
}Команда topaz check a.tpz --root . сообщает о проверенном цикле:
error[TPZ3006]: import cycle: a -> b -> a
--> a.tpz:1:8
|
1 | import b
| ^
a.tpz: 1 diagnosticКаждое ребро импорта участвует в проверке, даже если импортированное имя используется только как тип. Разорвите цикл: перенесите общие объявления в третий ациклический модуль или оставьте зависимость только в одном направлении. Исключения для циклов, содержащих только типы, нет.
Точные границы
Текущий синтаксис модулей не включает use, строковые или шаблонные пути,
одновременные псевдоним и список выбора, списки экспорта, групповой экспорт,
повторный экспорт, переименование на месте экспорта и импорт только ради
побочного эффекта. export let mut также отклоняется. Импорт не может выйти
за пределы корня, а пространство имён не открывает закрытые члены.
Продолжите с Первым приложением, чтобы собрать полностью проверенный пакет, с разделом Пакеты и распространение для манифеста и файла блокировки и со страницей Запрещённые и отложенные формы для знакомых форм модулей, которые Топаз намеренно не принимает.