Топаз сочетает мощную статическую систему типов с интеллектуальным выводом типов, позволяя писать безопасный, но краткий код. Компилятор автоматически выводит типы, когда вы их не указываете, но при необходимости можно быть явным. 🎯
🔢 Примитивные типы
Целые числа и вещественные
// Целочисленные типы
let возраст: int = 25
let большоеЧисло: bigint = 9999999999999999999
// Типы с плавающей точкой
let цена: float = 19.99
let точноеЧисло: double = 3.141592653589793
// Просто с выводом типов
let счёт = 95 // выводится как int
let среднее = 87.5 // выводится как float
Булев тип
let активен = true
let естьПраваАдмина = false
// Использование в условиях
if активен {
print("Сервис активен")
}
Символы и строки
// Символ (одиночный)
let оценка: char = 'A'
let эмодзи: char = '🎉'
// Строка
let имя = "Иван Топаз"
let длинноеПредложение = "Добро пожаловать в Топаз, язык, где код становится поэзией!"
// Интерполяция строк
let приветствие = "Привет, {имя}! Хорошая сегодня погода."
print(приветствие) // "Привет, Иван Топаз! Хорошая сегодня погода."
📊 Типы коллекций
Массивы
// Объявление и инициализация массива
let числа: [int] = [1, 2, 3, 4, 5]
let имена = ["Алиса", "Боб", "Чарли"] // выводится как [string]
// Манипуляции с массивом
let первый = числа[0] // 1
числа.push(6) // [1, 2, 3, 4, 5, 6]
let длина = числа.length() // 6
// Операции в функциональном стиле
let квадраты = числа.map(x => x * x)
let чётные = числа.filter(x => x % 2 == 0)
Объекты
// Определение объекта
let пользователь = {
имя: "Иван Топаз",
возраст: 28,
почта: "ivan@example.com",
активен: true
}
// Доступ к свойствам
print(пользователь.имя) // "Иван Топаз"
пользователь.возраст = 29 // изменение значения
// Объект с методами
let калькулятор = {
значение: 0,
добавить: function(x: int) -> int {
this.значение += x
return this.значение
},
умножить: function(x: int) -> int {
this.значение *= x
return this.значение
}
}
калькулятор.добавить(10).умножить(2) // цепочка методов
🏗️ Продвинутые типы
Тип Option
// Тип Option для безопасности от null
let результатПоиска: Option<string> = None
let имяПользователя: Option<string> = Some("admin")
// Безопасная обработка с сопоставлением образцов
match имяПользователя {
case Some(имя) => print("Добро пожаловать, {имя}!")
case None => print("Требуется авторизация")
}
// Безопасная обработка с ?. и ??
let длина = имяПользователя?.length ?? 0
Тип Result
// Тип Result для обработки ошибок
function прочитатьФайл(путь: string) -> Result<string, Error> {
if файлСуществует(путь) {
Ok(прочитатьСодержимоеФайла(путь))
} else {
Err(Err("Файл не найден"))
}
}
// Безопасная обработка ошибок
match прочитатьФайл("data.txt") {
case Ok(содержимое) => print("Содержимое файла: {содержимое}")
case Err(ошибка) => print("Произошла ошибка: {ошибка.message}")
}
Объединённые типы (Union Types)
// Тип, который может быть одним из нескольких типов
type ID = int | string
type Статус = "ожидание" | "обработка" | "завершено" | "ошибка"
let идПользователя: ID = 12345
let статусЗадачи: Статус = "обработка"
// Обработка для конкретного типа с сопоставлением образцов
function показатьID(id: ID) -> string {
match id {
case int => "Числовой ID: {id}"
case string => "Строковый ID: {id}"
}
}
🧬 Дженерик типы
Дженерик функции
// Дженерик функция с параметрами типа
function создатьМассив<T>(значение: T, количество: int) -> [T] {
let результат: [T] = []
for i in 0..количество {
результат.push(значение)
}
return результат
}
let массивЧисел = создатьМассив(42, 5) // [42, 42, 42, 42, 42]
let массивСтрок = создатьМассив("привет", 3) // ["привет", "привет", "привет"]
Дженерик структуры
// Определение дженерик структуры
struct Контейнер<T> {
значение: T,
function установитьЗначение(новоеЗначение: T) {
this.значение = новоеЗначение
}
function получитьЗначение() -> T {
return this.значение
}
}
let числовойКонтейнер = Контейнер { значение: 100 }
let строковыйКонтейнер = Контейнер { значение: "Привет" }
🎨 Псевдонимы типов
// Даём простые имена сложным типам
type ИнфоПользователя = {
имя: string,
возраст: int,
почта: string,
разрешения: [string]
}
type ФункцияОбратногоВызова = function(данные: string) -> void
type ОбновительСостояния<T> = function(предыдущееСостояние: T) -> T
// Пример использования
let администратор: ИнфоПользователя = {
имя: "Админ Пользователь",
возраст: 35,
почта: "admin@topaz.ooo",
разрешения: ["чтение", "запись", "удаление"]
}
🔄 Преобразование типов
// Явное преобразование типов
let строковоеЧисло = "123"
let число = int(строковоеЧисло) // 123
let вещественное = float(число) // 123.0
let обратноВСтроку = string(вещественное) // "123.0"
// Безопасное преобразование типов
let результат = tryInt("abc") // Option<int>
match результат {
case Some(значение) => print("Преобразование успешно: {значение}")
case None => print("Преобразование не удалось")
}
// Проверка типа
let значение: any = "Привет"
if значение is string {
print("Это строка: {значение as string}")
}
✨ Продвинутые паттерны
Деструктурирующее присваивание
// Деструктурирование массива
let [первый, второй, ...остальные] = [1, 2, 3, 4, 5]
print(первый) // 1
print(остальные) // [3, 4, 5]
// Деструктурирование объекта
let { имя, возраст } = пользователь
print("Имя: {имя}, Возраст: {возраст}")
// Деструктурирование в параметрах функции
function поприветствовать({ имя, возраст }: { имя: string, возраст: int }) {
print("Привет, {имя}! Вам {возраст} лет.")
}
Защитники типов
// Пользовательский защитник типа
function этоСтрока(значение: any): значение is string {
match значение {
case _: string => true
case _ => false
}
}
function безопаснаяОбработка(значение: any) {
if этоСтрока(значение) {
// значение здесь обрабатывается как тип string
print(значение.toUpperCase())
}
}
🚀 Практическое применение
// Практические определения типов для реальных проектов
type ОтветAPI<T> = {
успех: boolean,
данные: Option<T>,
ошибка: Option<string>,
кодСостояния: int
}
type Пользователь = {
id: int,
имя: string,
почта: string,
датаСоздания: Date
}
// Определение API функции (автоматическая асинхронность; ручное ожидание не требуется)
function получитьПользователя(id: int) -> ОтветAPI<Пользователь> {
let ответ = fetch("/api/users/{id}")
if ответ.ok {
let данныеПользователя = ответ.json()
return {
успех: true,
данные: Some(данныеПользователя),
ошибка: None,
кодСостояния: ответ.status
}
} else {
return {
успех: false,
данные: None,
ошибка: Some("Пользователь не найден"),
кодСостояния: ответ.status
}
}
}
Система типов Топаза обеспечивает как безопасность, так и выразительность. Благодаря выводу типов вы можете писать краткий код, предотвращая ошибки точными спецификациями типов при необходимости. 🎯