Переменные, массивы и функции в QLua (lua)

Автор записи: Дмитрий (Admin)
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 8, среднее: 5,00 из 5)
Загрузка...

Qlua-основыВ Qlua есть следующие типы переменных:

   nil (неопределенный),
   boolean (логический),
   number (числовой),
   string (строковый),
   function (функция в Lua является типом данных),

а также, есть массивы (таблицы Lua), в т.ч. многомерные, которые могут содержать в себе все вышеперечисленные типы данных.

Для того, чтобы объявить переменную в Qlua, достаточно присвоить ей значение. Язык Qlua сам определит к какому типу отнести переменную.

Примеры:

A = true; -- Теперь переменная A имеет логический тип boolean
   -- в QLua(Lua) все значения являются TRUE, кроме nil и FALSE
 
B = 1;
C = 1.5;
-- Переменные B и C имеют числовой тип number, который может содержать как целые числа, так и числа с дробной частью
 
D = "Текст"; -- Переменная D имеет строковый тип string
 
E = {}; -- Переменная E теперь является массивом нулевой длинны
-- Массив в QLua может хранить внутри себя значения РАЗНЫХ! типов одновременно
-- Так присваиваются значения элементам:
E[1] = 10; -- ВАЖНО !!! Элементы массива в QLua, по умолчанию, индексируются, начиная с 1, а не с 0,
   -- хотя ключами(индексами) могут быть и отрицательные числа и слова и строки
   -- пример инициализации:
   F = {green = "Зеленый", [-10] = 30};
   -- НЮАНС!!!
   G = {good year = 2015}; -- такая инициализация вызовет ошибку
   G["good year"] = 2015;  -- а так ошибки не будет
   -- примеры добавления:
   F["apple"] = "Яблоко";
   F[-20] = 12345;
   E[2] = "Текст";
 
-- МНОГОМЕРНЫЕ массивы создаются так же, как и одномерные, мерность зависит от количества вложенных фигурных скобок:
A = {{{}}}; -- объявлен трехмерный массив
A[1][1][1] = "Значение"; -- пример обращения к массиву
 
-- Массивы в QLua являются таблицами, по-этому к ним можно применять функции из таблицы table языка lua:
table.concat(Array, str, i, j) -- Выполняет конкатенацию элементов массива в одну строку и возвращает ее
   -- Array - это исходный массив,
   -- str (необязательный параметр) - строка, вставляемая между элементами
   -- i (необязательный параметр) - начальный индекс (по умолчанию, 1)
   -- j (необязательный параметр) - конечный индекс (по умолчанию, индекс последнего элемента массива)
table.insert(Array, i, new_element) -- Вставляет элемент new_element в массив Array по индексу i, сдвигая существующие элементы
   -- i (необязательный параметр) - по умолчанию, новый элемент добавляется в конец массива, увеличивая его на 1 элемент
table.maxn(Array); -- Возвращает максимальный положительный числовой индекс, если таковых нет, возвращает 0
table.remove(Array, i); -- Удаляет элемент таблицы по индексу i
   -- i (необязательный параметр) - по умолчанию, удаляется последний элемент массива
table.sort(Array, func); -- Сортирует элементы массива, размещая их по определенному правилу
   -- func (необязательный параметр) - по умолчанию, функция сортирует элементы по возрастанию, применяя сравнение "<",
     -- но можно применить свой порядок, для этого, вторым параметром нужно передать функцию, принимающую 2 параметра, 
     -- которая будет возвращать true, если параметр 1 меньше параметра 2.      
     -- Пример:      
     Arr = {2,4,3,1,5};      
     function MySort(a,b)         
        if a > b then 
           return true; 
        else 
           return false; 
        end;
     end;
     table.sort(Arr);         -- В результате в массиве Arr будет такой порядок {1,2,3,4,5}
     table.sort(Arr, MySort); -- В результате в массиве Arr будет такой порядок {5,4,3,2,1}
 
-- Чтобы узнать количество элементов в массиве, применяется оператор "#"
-- в предыдущем примере #Arr вернет 5, но есть один ВАЖНЫЙ МОМЕНТ!!!:
Arr[2] = nil; -- теперь в массиве содержатся значения {5,3,2,1}, а индексы (1,3,4,5), т.е. индекс 2 отсутствует,
-- сейчас #Arr вернет 1, т.к. элемент по индексу 2 не существует

Все переменные, объявленные выше, являются ГЛОБАЛЬНЫМИ по типу видимости, т.е., объявив так переменную в одной функции, можно будет использовать ее значение в любой другой функции, находящейся в том же скрипте. Можно объявить переменную ЛОКАЛЬНОГО типа, использовать которую можно будет только внутри той функции, в которой Вы ее создали. Для этого перед именем переменной нужно поставить идентификатор local.

Примеры:

A = 1; -- ГЛОБАЛЬНАЯ, видна везде в скрипте
local B = 2; -- ЛОКАЛЬНАЯ, но, так как объявлена в основном теле скрипта, а не внутри функции, видна везде в скрипте
 
function F1()
   -- Здесь видны переменные A и B, можно как брать из них значения, так и изменять их
 
   C = 3; -- Объявлена ГЛОБАЛЬНАЯ переменная
   local D = 4; -- Объявлена ЛОКАЛЬНАЯ переменная
   local A = 5; -- Объявлена НОВАЯ ЛОКАЛЬНАЯ переменная, которая не изменила значение ранее объявленной переменной A
end;
 
function F2()
   -- Здесь видны переменные A(первая), B и C, можно как брать из них значения, так и изменять их
   -- Если обратиться здесь к переменной A, то увидим, что она, по-прежнему, равна 1
   -- Переменная D здесь не видна 
end;

Функции

-- Объявление:
function Name(параметр1, параметр2,...)
end;
-- следующая запись эквивалентна:
Name = function(параметр1, параметр2,...)
end;
   -- Функция в QLua(Lua) может иметь входные параметры, а может и не иметь
   -- Параметры, это локальные для данной функции переменные, значения которых передаются при вызове функции
-- Функция в QLua(Lua) может иметь переменное число параметров
-- пример 1:
function F1(a,b,...)
end;
   -- Пример вызова:
   F1(1,2,3,4);
   -- Значение 1 присвоится переменной a
   -- Значение 2 присвоится переменной b
   -- Для оставшихся значений (3 и 4), существует встроенная переменная arg, у которой есть поле n,
      -- в которую заносится количество переданных дополнительных значений, в данном случае arg.n равно 2
   -- Значение 3 присвоится переменной arg[1] 
   -- Значение 4 присвоится переменной arg[2]
 
-- пример 2:
function F2(...)
end;
   -- Пример вызова:
   F2(1,2,3);
   -- Значение 1 присвоится переменной arg[1]
   -- Значение 2 присвоится переменной arg[2]
   -- Значение 3 присвоится переменной arg[3]
   -- arg.n равно 3
 
-- Функции в QLua(Lua) могут не возвращать, или возвращать одно и более значений,
   -- для этого служит оператор return
-- Пример:
function F()
   return 1,2,3;
end;
-- Вызов 1:
A = F();
-- A[1] получит значение 1
-- A[2] получит значение 2
-- A[3] получит значение 3
-- Вызов 2:
A,B,C = F();
-- A получит значение 1
-- B получит значение 2
-- C получит значение 3
-- Вызов 3:
_,_,A = F();
-- A получит значение 3
-- Символ "_" служит в QLua(Lua) для замены ненужных переменных

QLua поддерживает параллельное присваивание:

   -- Запись
   a,b,c = 1,2,3;
   -- эквивалентна записи
   a = 1;
   b = 2;
   c = 3;

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Добавить комментарий

Переменные, массивы и функции в QLua (lua): 166 комментариев

  1. Доброго времени, Господа! Подскажите, можно ли с помощью table.insert вставлять элементы в многомерный массив, если их парное количество совпадает?

    1. не совсем понятно, что вы имели в виду. ответ: да, можно, но, скорее всего, вам это не нужно.

      ps: в lua нет массивов, таблицы - это key-value хранилища. получая значение "по индексу" выражением вроде a = tbl[5] - на самом деле вы достаете из dict некое значение с ключом типа number, которое имеет значение 5. все эти insert, remove - они просто перенумеровывают ключи, из-за этого они довольно медленные, особого смысла в их использовании нет.

      1. Просто размышляю, с чем проще и удобнее работать: может со строковыми функциями? Например, создаём многомерный массив с параметрами опционов, которые отбираем при помощи фильтров перебираемых таблиц инструментов, когда получаем необходимый опцион - добавляем в таблицу, например, страйк, открытый интерес с помощью table.insert , указывая часть (ключ) таблице (например "Strike"), или же перебираем с помощью string.gmatch, а потом помещаем в таблицу. Или же проще и быстрее работать с массивами традиционным способом без строковых функций?

      2. Или же вот, например, создать таблицу параметров опционов наподобие getQuoteLevel2 только для доски опционов, поскольку специальной функции для получения данных из доски опционов нет. После этого можно спокойно обрабатывать все цены, греки и другие параметры для построения индикаторов на графике базового актива.

        1. вы смотрите на проблему не с той стороны. так как вы, насколько я понял, пишите индикатор, то чтобы он не тормозил, нужно чтобы расчет занимал минимальное время. соответственно, вам нужно организовать данные так, чтобы их было быстрее (и проще, если получится) доставать для расчета. подумайте, какие данные вам нужны, как вы к ним будете доступаться из алгоритма расчета вашего индикатора и все станет просто и логично.

          1. я вообще заметил странную вещь в Квике! такое впечатление, что индикатор с глобальными переменными работает быстрее. хотя это как-то странно! но, поскольку, я больше трейдер, чем программист, поэтому многие вещи мне в диковинку. поначалу покупал что-то- и в итоге получал не то, что надо или то, что не может нормально работать в виде скомпилированного кода. вот и приходится хоть насколько-нибудь немного самому пытаться понять суть некоторых вещей. так что заранее извиняюсь за порой глупые вопросы. я так понимаю, Вы ребята очень подкованы в вопросах разработок. и вообще - данный ресурс, по моему убеждению, лучший в своём роде. поэтому очень Вам благодарен за помощь и поддержку!

            1. очевидно, "индикатор с глобальными переменными" работает не так, как другой индикатор потому, что различаются алгоритмы. от того, что вы пишите i = 1 вместо local i = 1 в функции OnCalculate() - на скорости это сказывается примерно никак.

  2. добрый вечер!
    нуждаюсь в помощи...
    пишу индикатор...
    Settings=
    {
    Name = "xerman",
    period=4,
    line=
    {
    {
    Name = "High",
    Type =TYPE_LINE,
    Width = 1,
    Color = RGB(120,90, 140)
    },
    {
    Name = "Low",
    Type =TYPE_LINE,
    Width = 1,
    Color = RGB(120,90,140)
    }
    }
    }

    function Init()
    return 2
    end
    function OnCalculate(index)
    local induc=0
    local vxod=60
    local diap=math.abs(C(index)-C(index-1))
    t={}
    t[#t+1]= diap
    Period = Settings.period
    if #t<Period then
    return nil
    else
    local sum=0
    for i=#t-Period+1, #t do
    sum=sum+diap
    end
    induc=sum/Period
    end
    return induc, vxod
    end

    мне нужно посчитать среднее значение нескольких последних разниц цен закрытия.... не понимаю синтаксис языка... в общей сложности 10 часов провел переписывая код, вставляя в график и получая шлямбуром по подбородку....
    я так понимаю у меня есть переменная diap и когда я просто пишу return diap, то индикатор строится и показывает мне значения разниц, а вот как среднюю то от них взять???????????????????????????????????????
    я догадываюсь что надо создать массив в который эта переменная diap будет наполняться новыми значениями, но как это реализовать хоть убейте не пойму....
    помогите пожалуйста, умоляю....

    1. Здравствуйте, надеюсь поможет

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      main = function()
         -- Создали массив
         Arr = {}
         -- Заполнили его значениями
         for i=1, 100 do
            Arr[i] = i
         end
         -- Вычисляем и выводим средние за каждые 5 последних значений (период 5)
         for i=5, 100, 5 do
            local Sum = 0
            for j=4,0,-1 do
               Sum  = Sum  + Arr[i-j]
            end
            message(tostring(Sum/5))
         end
      end
      1. спасибо огромное, правда решил задачу без массива уже, но то что вы написали очень мне поможет в моих следующих муках. еще раз спасибо огромное)

          1. вобщем.... тупица я непрошибаемый... ничего не выходит у меня с массивами...
            доброго времени суток=)
            T={} - создал массив
            function onalltrade(alltrade) - написал функцию
            if alltrade.sec_code == "RIZ9" then
            local a=alltrade.qty - написал что переменная должна получать из функции
            end
            return a - вернул значение переменной
            end
            T[i]=i - а вот тут пытаюсь ежика родить.............. что делать не понимаю.....
            for i=a, (а вот до чего здесь писать??????????????????? p.s. for i=1, 100 do - это ясно. а в моем то случае как мне получить этот злосчастный массив состоящий из {a1,a2,a3,......................an}?????????????????????????????????????????????????????????)

            1. "return a" у вас возвращает nil, т.к. она объявлена локально внутри блока if .... end, и на выходе из блока ее уже нет.
              function onalltrade(alltrade)
              if alltrade.sec_code == "RIZ9" then
              return alltrade.qty
              end
              return 0
              end