API Basic Arrays - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki
DIM / REDIM / PRESERVE
ClassicUO • Basic
DIM создаёт динамический массив; REDIM заменяет его хранилище. PRESERVE копирует значения по совпадающим индексам. Размерность задаётся включительной верхней границей, а не количеством элементов. Перед чтением заполните ячейки.
Точный синтаксис
DIM name[upper]
DIM name(upper) AS type
DIM grid[xUpper][yUpper]
DIM grid(xUpper, yUpper)
REDIM name[upper]
REDIM PRESERVE name[upper]
name[index] = value
GetArrayLength(name)
Параметры
name— name: имя массива. DIM объявляет его, REDIM записывает новое хранилище в существующую переменную. Чтение и запись: items[i], grid[x][y], с квадратными скобками.upper— upper: выражение, преобразуемое в Integer и вычисляемое однократно слева направо. DIM items[2] создаёт три ячейки, 0..2. -1 создаёт пустую размерность; меньшая граница и переполнение длины ошибочны. Практический размер ограничен памятью.PRESERVE— PRESERVE: необязательное слово после REDIM. Рекурсивно копирует пересечение индексов; при уменьшении значения за новой границей теряются. Без него новые ячейки не инициализированы.AS type— AS type: допускается в объявлении массива DIM как аннотация; не задаёт тип, начальные значения или преобразование элементов. В одном массиве могут быть значения разных видов.
Возвращает
DIM и REDIM не возвращают значения (Unit). items[i] возвращает сохранённое значение с его фактическим видом: Integer, Decimal, String, Array или Object. Чтение неинициализированной ячейки вызывает ошибку, а не 0 или FALSE. GetArrayLength(array) возвращает внешнюю длину как Integer; для не-массива — 0.
Поведение
- В объявлении допустимы круглые скобки: DIM grid(1, 2) означает grid[1][2], две строки по три ячейки. Вызовы функций в границах сохраняются. Обращение к элементу остаётся grid[1][2]; круглые скобки в выражении означают вызов функции.
- Обычное присваивание и передача ByVal копируют ссылку на массив, а не элементы. Изменения общей ячейки видны через другие ссылки. REDIM привязывает новый массив; прежние ссылки сохраняют старый. PRESERVE копирует совпадающие координаты вложенных массивов, но не клонирует произвольные объекты целиком.
- Индексы начинаются только с нуля. Инициализатор внутри DIM/REDIM, например DIM items[2]=5, отклоняется с SC014: заполняйте ячейки отдельными строками. Неверный индекс и чтение отсутствующего или неинициализированного элемента вызывают обрабатываемые ошибки.
- Это диалект Basic проекта. Динамические виды элементов и многомерный PRESERVE отличаются от типизированных массивов VB.NET. Логическое значение в ячейке хранится как 1/0; произвольное число или длина массива не являются флагом успеха.
- RETURN array возвращает ссылку на массив: данные остаются доступны после завершения функции. Присваивание результата другой переменной не копирует элементы. Это позволяет создавать массивы в общей функции и сохранять результат в поле Module. Самостоятельные запуски скрипта создают новые массивы при повторном выполнении DIM.
Примеры
1. Сумма заполненных элементов
# Abs(-2) даёт верхнюю границу 2: Main создаёт 3 ячейки и записывает 2, 4, 6. Sum получает общую ссылку ByVal, перебирает индексы от 0 до GetArrayLength(items)-1 и возвращает 12. Функция полностью приведена, не изменяет ячейки и допускает пустой массив.
Option Explicit On
FUNCTION Sum(ByVal items)
VAR total = 0
VAR i = 0
FOR i = 0 TO GetArrayLength(items) - 1
total += items[i]
NEXT
RETURN total
END FUNCTION
SUB Main()
DIM items(Abs(-2))
items[0] = 2
items[1] = 4
items[2] = 6
RETURN Sum(items)
END SUB
Разбор параметров и выполнения:
Abs(-2) даёт верхнюю границу 2: Main создаёт 3 ячейки и записывает 2, 4, 6. Sum получает общую ссылку ByVal, перебирает индексы от 0 до GetArrayLength(items)-1 и возвращает 12. Функция полностью приведена, не изменяет ячейки и допускает пустой массив.
2. Увеличить с сохранением
# В values записаны 7 и 8. REDIM PRESERVE values(2) создаёт 3 ячейки и копирует индексы 0 и 1. Новую ячейку 2 нужно заполнить: записываем 9. Main возвращает 7*100+8*10+9=789.
Option Explicit On
SUB Main()
DIM values[1]
values[0] = 7
values[1] = 8
REDIM PRESERVE values(2)
values[2] = 9
RETURN values[0] * 100 + values[1] * 10 + values[2]
END SUB
Разбор параметров и выполнения:
В values записаны 7 и 8. REDIM PRESERVE values(2) создаёт 3 ячейки и копирует индексы 0 и 1. Новую ячейку 2 нужно заполнить: записываем 9. Main возвращает 7100+810+9=789.
3. Общие ссылки и новое хранилище
# grid содержит две строки по две ячейки. alias ссылается на тот же массив: alias[0][1]=9 меняет и grid. PRESERVE увеличивает grid до трёх строк, сохраняет 9, а alias остаётся с двумя строками. Возврат "9:3:2": сохранённое значение, новая внешняя длина, длина старой ссылки.
Option Explicit On
SUB Main()
DIM grid[1][1]
grid[0][1] = 4
VAR alias = grid
alias[0][1] = 9
REDIM PRESERVE grid[2][1]
RETURN CStr(grid[0][1]) + ":" + CStr(GetArrayLength(grid)) + ":" + CStr(GetArrayLength(alias))
END SUB
Разбор параметров и выполнения:
grid содержит две строки по две ячейки. alias ссылается на тот же массив: alias[0][1]=9 меняет и grid. PRESERVE увеличивает grid до трёх строк, сохраняет 9, а alias остаётся с двумя строками. Возврат "9:3:2": сохранённое значение, новая внешняя длина, длина старой ссылки.