Oubi, преимущества:
1. Явное указание пространства имен в котором нужна ваша переменная:
// init.sqf
MyVariable = 1;
// В каком-то скрипте
MyVariable; // 1
// В каком-то другом скрипте
MyVariable; // nil
Разница между скриптами в том, например, что первый был вызван из триггера, а второй из UI, где часто встречается следующая конструкция смены пространства имен:
with uiNamespace do { ... };
А использовав вместо обычного имени переменной следующую конструкцию:
missionNamespace getVariable "MyVariable";
Вы бы всегда получали нужное значение, независимо от контекста выполнения
2. По-умолчанию всегда используется missionNamespace, с помощью команды with-do, упомянутой выше, вы можете сменить пространство имен на uiNamespace, parsingNamespace или profileNamespace. Но с помощью setVariable/getVariable вы можете использовать в качестве пространства имен почти любой объект в Арме! Тем самым реализуя концепцию Объектно-ориентированного программирования:
{ _x setVariable ["MyVariable", _forEachIndex]; } forEach [unit1, unit2, unit3];
unit1 getVariable "MyVariable"; // 0
unit2 getVariable "MyVariable"; // 1
unit3 getVariable "MyVariable"; // 2
MyVariable; // nil
3. in-engine проверка на определение переменной:
MyVariable; // nil
if (isNil "MyVariable") then { 1; } else { MyVariable; }; // 1
Или просто:
missionNamespace getVariable "MyVariable"; // nil
missionNamespace getVariable ["MyVariable", 1]; // 1
4. Т. к. для указания переменной вам нужно ее название в типе STRING, то это позволяет генерировать имя переменной:
{ missionNamespace setVariable [format ["unit%1", _forEachIndex], _x]; } forEach allUnits;
Теперь каждый юнит имеет переменную ссылающуюся на него с именем unit + индекс. Хоть этот код полностью бесполезен, но попробуйте тоже самое провернуть, когда у вас 100 юнитов, без помощи setVariable... у вас банально закончится терпение на 5 или 10 юните!
Так же это позволяет использовать передачу аргументов по "ссылке". Хоть в SQF все переменные и передаются по ссылке, но из-за особенностей реализации команд модифицируются по ссылке только массивы. А иногда нужно модифицировать и другие типы данных:
MyVariable = ""; // ""
[missionNamespace, "MyVariable"] call MyFunction;
MyVariable; // "Hello world!";
// MyFunction
params ["_namespace", "_variable"];
_namespace setVariable [_variable, "Hello world!"];
5. Sharing значения переменной в сетевой игре. Часто можно увидеть следующую конструкцию:
MyVariable = 1;
publicVariable "MyVariable";
Это отправка значения переменной всем другим клиентам в сетевой игре. Но это можно сделать только для переменных в missionNamespace, в то время как с помощью setVariable это можно сделать для переменных практически в любом пространстве:
unit1 setVariable ["MyVariable", 1, true];
И через некоторое время, когда переменная будет синхронизирована, на других машинах в сети можно будет получить:
unit1 getVariable "MyVariable"; // 1
6. Обычная переменная накладывает на свое имя следующие ограничения: только латинские буквы, цифры и нижнее подчеркивание, первый символ не цифра. Имя переменной задаваемой и получаемой с помощью этих команд может быть любым:
missionNamespace setVariable ["This is my variable!", 1];
missionNamespace getVariable "This is my variable!"; // 1
This is my variable! = 1; // Error Missing ;
7. Имя переменной будет проверено на совпадение с зарезервированными именами и выведется понятное сообщение:
missionNamespace setVariable ["player", 1]; // Error Reserved variable in expression
player = 1; // На клиента: Error Generic error in expression На выделенном сервере может вообще ничего не написать
Недостатки: Он всего один - скорость:
Result:
0.0004 ms
Cycles:
10000/10000
Code:
MyVariable
Result:
0.0007 ms
Cycles:
10000/10000
Code:
missionNamespace getVariable "MyVariable"
Result:
0.0016 ms
Cycles:
10000/10000
Code:
missionNamespace getVariable ["MyVariable", 1]
Но тут стоит сказать одну вещь: доступ к локальным переменным значительно быстрее доступа к глобальным переменным:
Result:
0.0003 ms
Cycles:
10000/10000
Code:
_myVariable
Из чего вытекает следующее:
Result:
0.0549 ms
Cycles:
10000/10000
Code:
for "_i" from 0 to 99 do { MyVariable; }
Result:
0.044 ms
Cycles:
10000/10000
Code:
private _MyVariable = missionNamespace getVariable ["MyVariable", 1]; for "_i" from 0 to 99 do { _MyVariable; }
Сообщение отредактировал vlad333000: 18 December 2018 - 22:59