Topazdocs
Основные концепции

Переменные и область видимости

Освойте объявление переменных, управление областью видимости и контроль изменяемости в Топазе. Изучите различия между let, let mut, const и поймите лексическую область видимости и поведение замыканий.

Примечание о библиотечных именах: вспомогательные имена вне минимума стандартной библиотеки (списокПользователей и т.д.) являются иллюстративными заполнителями, а не каноническими API.

Переменные и область видимости являются основой программирования. Топаз предоставляет современную и безопасную систему переменных, которая уменьшает количество ошибок и повышает ясность кода.

Объявление переменных

let - Неизменяемые переменные (по умолчанию)

TOPAZ
// Все переменные по умолчанию неизменяемы
let имя = "Иван Топаз"
let возраст = 25
let активен = true

// Нельзя изменить после определения
// имя = "Другое имя"  // Ошибка компиляции!

В публичной документации Topaz используйте let mut, когда переменная переназначается или коллекция изменяется на месте. let остаётся вариантом по умолчанию для стабильных привязок.

let mut - Изменяемые переменные

TOPAZ
// Используйте let mut, когда нужно изменять значения
let mut счёт = 100
let mut сообщение = "Начальное сообщение"

// Значение можно изменить
счёт = 95
сообщение = "Обновлённое сообщение"

print("Текущий счёт: {счёт}")  // "Текущий счёт: 95"

const - Константы времени компиляции

TOPAZ
// Константы, определяемые во время компиляции
const MAX_SIZE: int = 1000
const APP_NAME: string = "Топаз Calculator"
const PI: float = 3.141592653589793

// Константы верхнего уровня, доступные ниже в этом файле
const настройкиПоУмолчанию = {
    язык: "Русский",
    тема: "тёмная",
    автосохранение: true
}

Вывод типов и явные типы

TOPAZ
// Вывод типов (рекомендуется)
let выведенноеЧисло = 42           // int
let выведеннаяСтрока = "Привет"    // string
let выведенныйМассив = [1, 2, 3]   // Array<int>

// Явные типы (когда необходимо)
let явноеЧисло: int = 42
let явнаяСтрока: string = "Привет"
let явныйМассив: Array<int> = [1, 2, 3]

// Явные типы помогают в сложных случаях
let данныеПользователя: { имя: string, возраст: int } = {
    имя: "Разработчик Иванов",
    возраст: 30
}

Правила области видимости

Глобальная область видимости

TOPAZ
// Верхний уровень файла - глобальная область видимости
let глобальнаяПеременная = "Доступна везде"
const глобальнаяКонстанта = 100

function использоватьВезде() {
    print(глобальнаяПеременная)      // Доступна
    print("{глобальнаяКонстанта}")   // Доступна
}

Область видимости функции

TOPAZ
function калькулятор(a: int, b: int) -> int {
    // Параметры функции также принадлежат области видимости функции
    let результат = a + b        // Область видимости функции
    let mut временноеЗначение = a * 2 // Область видимости функции
    
    print("Результат: {результат}")
    return результат
}

// print(результат)  // Ошибка! Нельзя получить доступ вне функции

Блочная область видимости

TOPAZ
function примерОбластиВидимости() {
    let внешняяПеременная = "снаружи"
    
    if true {
        let внутренняяПеременная = "внутри"      // Блочная область видимости
        let mut блочнаяИзменяемая = 10               // Блочная область видимости
        
        print(внешняяПеременная)                 // Доступна (внешняя область)
        print(внутренняяПеременная)              // Доступна (та же область)
    }
    
    print(внешняяПеременная)                     // Доступна
    // print(внутренняяПеременная)               // Ошибка! Нельзя получить доступ вне блока
}

Область видимости цикла

TOPAZ
// Переменные цикла for имеют область видимости цикла
for i in 0..5 {
    let переменнаяЦикла = i * 2
    print("i: {i}, значение: {переменнаяЦикла}")
}

// print(i)  // Ошибка! Нельзя получить доступ вне цикла

Topaz наряду с for предоставляет и операторы while (см. страницу управления потоком); к их телам применяются те же правила блочной области видимости.

Затенение переменных

TOPAZ
let имя = "Иван Топаз"

function примерЗатенения() {
    let имя = "Разработчик Петров"        // Затеняет глобальное имя
    print("В функции: {имя}")             // "В функции: Разработчик Петров"
    
    {
        let имя = "Дизайнер Сидоров"       // Затеняет имя функции
        print("В блоке: {имя}")            // "В блоке: Дизайнер Сидоров"
    }
    
    print("После блока: {имя}")           // "После блока: Разработчик Петров"
}

print("Глобальное: {имя}")               // "Глобальное: Иван Топаз"
примерЗатенения()

Затенение канонично через вложенные лексические области (как показано выше). Переобъявление того же имени в той же области не канонично для Topaz.

Замыкания и область видимости

TOPAZ
function создатьСчётчик(начальноеЗначение: int) -> () -> int {
    let mut счёт = начальноеЗначение           // Захватывается замыканием
    
    return () => {
        счёт += 1                          // Доступ к переменной внешней области
        счёт
    }
}

let счётчик1 = создатьСчётчик(0)
let счётчик2 = создатьСчётчик(100)

print("{счётчик1()}")  // 1
print("{счётчик1()}")  // 2
print("{счётчик2()}")  // 101
print("{счётчик1()}")  // 3

Сопоставление образцов и переменные

TOPAZ
let пользователь = {
    имя: "Иван Топаз",
    возраст: 28,
    работа: "Разработчик"
}

// Деструктурирование создаёт новые переменные
let { имя, возраст } = пользователь
print("Имя: {имя}, Возраст: {возраст}")

// Привязка переменных в match
match пользователь.возраст {
    case возраст if возраст < 20 => print("Вероятно, студент")
    case возраст if возраст < 30 => print("Молодой специалист")
    case возраст => print("Опытный: {возраст} лет")
}

// Сопоставление образцов массива
let оценки = [95, 87, 92, 88]
match оценки {
    case [первая, вторая, ..остальные] => {
        print("Первая: {первая}")
        print("Вторая: {вторая}")
        print("Остальные: {остальные}")
    }
    case _ => print("Нужно как минимум две оценки")
}

Продвинутые паттерны области видимости

Блок-выражения для изоляции области видимости

TOPAZ
// Блок-выражение для изоляции области видимости
let результат = {
    let временныйРасчёт = 10 * 20
    let корректировка = 50
    временныйРасчёт + корректировка
}

print("{результат}")  // 250
// временныйРасчёт, корректировка недоступны вне блока

Область видимости модуля

Topaz v5.2 добавляет систему модулей / import / export. Многофайловая организация, правила видимости и привязки модульной области рассматриваются в Модулях и видимости; примеры на этой странице остаются в пределах одного файла.

Лучшие практики

1. Используйте неизменяемость по умолчанию

TOPAZ
// Хорошо: используйте let по умолчанию
let конфигурация = {
    тема: "тёмная",
    язык: "Русский"
}

// Используйте let mut только при необходимости
let mut статусПрогресса = "начато"
статусПрогресса = "в процессе"
статусПрогресса = "завершено"

2. Осмысленные имена переменных

TOPAZ
// Плохой пример
let a = списокПользователей.length
let b = a * 2

// Хороший пример  
let общееКоличествоПользователей = списокПользователей.length
let удвоеннаяЁмкость = общееКоличествоПользователей * 2

3. Минимизируйте область видимости

TOPAZ
function обработатьДанные(исходныеДанные: Array<int>) -> Array<int> {
    let mut результат: Array<int> = []
    
    for элемент in исходныеДанные {
        // Переменные, нужные только в цикле, должны объявляться в цикле
        let преобразованноеЗначение = элемент * 2 + 1
        let проверенноеЗначение = if преобразованноеЗначение > 0 { преобразованноеЗначение } else { 0 }
        
        результат.push(проверенноеЗначение)
    }
    
    return результат
}

Советы по отладке

TOPAZ
// Отслеживайте привязки интерполированными print
let глобальнаяМетка = "build-42"

function выводИнформацииООбласти() {
    let локальнаяПеременная = "локальная"
    
    print("Переменные в текущей функции:")
    print("- локальнаяПеременная: {локальнаяПеременная}")
    print("- глобальнаяМетка: {глобальнаяМетка}")   // внешние привязки остаются доступными
}

Разрешение имён статично: использование имени, которого нет в области видимости, — это ошибка компиляции, поэтому писать проверку «определена ли эта переменная?» во время выполнения не нужно. Компилятор перехватит её до запуска программы.

Система переменных и области видимости Топаз обеспечивает как безопасность, так и ясность. С неизменяемостью по умолчанию, но позволяя изменяемость при необходимости, и чёткими правилами области видимости, вы можете писать предсказуемый код.