Перейти к контенту
Malandrinus

Язык Lua. Общие вопросы программирования

Рекомендуемые сообщения

С чего начинать и где взять.

 

Установка Lua:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106

 

Руководство «Программирование на языке Lua», третье издание:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308

Изменено пользователем Kirgudu
Ссылка на комментарий
7.9, все сделано так, что по идее не должно вообще ни с какими правками пересекаться

Vita sine libertate, nihil

Vita sine litteris - mors est

Ссылка на комментарий

К сведению. (и ещё раз возвращаясь к вопросам о скорости выполнения).

 

Хоть сам и говорил о правильном заполнении строгих числовых массивов посредством стандартной функции table.insert, но...

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

t[#t+1]=какое-то значение

происходит процентов на 25 быстрее чем table.insert

Ссылка на комментарий

Несколько вопросов\уточнений.

1. table.concat(tbl,sep,i,j)

Возвращает строку со значениями элементов массива, разделенных значением sep, элементы от i до j? Т.е. при

local tbl = {1,2,3,"one","two","three"}
local string = table.concat(tbl,"_",1,#tbl)

string будет равен "1_2_3_one_two_thee"?

2. Плохо искал и не нашел. Как строку "1234.5678" перевести в просто число 1234.5678? Т.е. есть переменная

local string = "1234.5678"

После каких то манипуляций будет что

string = 1234.5678

Изменено пользователем Desertir

ТЧ 1.0004. SAP и Trans mod

github

Ссылка на комментарий

Desertir

 

1. Верно. Возвратит именно такую строку. Для конкатенации всей таблицы аргументы 1 и #tbl указывать не обязательно. Достаточно написать :

local str = table.concat(tbl,"_")

2. При помощи функции tonumber :

local str = "1234.5678"
local num = tonumber(str)

3. Старайся не использовать в именах переменных имена зарезервированных глобальных переменных. Переменная string является именем глобальной таблицы для работы со строками. Объявляя local string = ... ты затираешь эту таблицу в области видимости новой переменной string. Всё ничего, пока значением переменной с именем string является строка (как в твоём примере). Если будет другое значение, то такое затирание приведёт к ошибке.

Изменено пользователем Gun12
Ссылка на комментарий

Мужики,такой вопрос Как правильно составить табличку. Суть. В таблицу сохраняется ключ, которому соответствует несколько значений...

 

С одним значение у меня проблем не возникло....

 

table.insert(tbl, Msg)

 

function SndNewsDeth()
local TblMsgDethVal = table.getn(TblMsgDeth)
if TblMsgDethVal ~= 0  then
Inx=math.random(table.getn(TblMsgDeth))
local Msg = TblMsgDeth[Inx]
send_tip(Msg,"Сообщение:", nil, nil,nil,nil)
--Удаляем сообщение из таблицы типсов.
table.remove(TblMsgDeth, Inx)
end
end

 

С этим мне удается сохранить только одну строку... Т.е только Msg, а мне бы хотелось сохранять не одно значение а еще несколько....

 

Как я понял, проще сделать несколько таблиц, и заполнять в них нужные мне значения но в одном порядке Inx , а потом так же удалять... Чем написать трехмерную таблицу ? Проблема в том , что я не знаю как такое сделать(Написать трехмерную таблицу),есть предположение делать сдвиг на +n , но что-то у меня не получается...

Изменено пользователем Vano_Santuri

Что-то кончается, что-то начинается...

Ссылка на комментарий

Vano_Santuri

Не совсем понял какую таблицу ты хочешь сделать. Какие параметры, как они должны быть сгруппированы.

 

Кстати, можно при помощи table.insert(tbl, Msg) вставлять не просто значение (строку), а можно вставлять таблицы, которые будут содержать все что тебе нужно:

local t ={

text="text1",

id=12,

stalker=true

}

table.insert(tbl,t)

Freedom

Ссылка на комментарий

_Призрак_,

 

Спасибо!!! Точно,это то, что мне было нужно!!!!

 

Только одно но, как мне вытащить из этой подтаблицы нужное значение

 

local t ={text="text1",id=12,stalker=true}
table.insert(tbl,t)

local Inx=math.random(table.getn(tbl))
local text = tbl[Inx][text]  -- Так прокатит? Взять рандомную таблицу, а из нее извлечь значение "text"?

Изменено пользователем Vano_Santuri

Что-то кончается, что-то начинается...

Ссылка на комментарий

Vano_Santuri

так прокатило бы если бы у тебя была бы такая таблица:

local t ={["text"]="text1",["id"]=12,["stalker"]=true}

 

Поэтому используй такой вариант:

local text = tbl[inx].text --Запрашиваем таблицу по индексу, а потом у подтаблицы запрашиваем парметр text

 

Кстати советую вместо table.getn(tbl) использовать #tbl - это не только короче, но еще и быстрее

Freedom

Ссылка на комментарий
_Призрак_, Спасибо!!! Реально помогло, облегчил много кода! Только один вопрос.Какой длины должна быть строка, чтоб не забился стек...

Что-то кончается, что-то начинается...

Ссылка на комментарий

Vano_Santuri

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

Только что я создал строку размером 100000 символов и вывел ее. Правда я делал это не в сталкере, а на чистом луа. Но чтобы у тебя что то переполнилось про работе со строками - что-то из разряда фантастики. У меня никогда этого не было

 

З.Ы. Давай переходить в Скриптование и спавн, а то нас здесь быстро разгонят

Freedom

Ссылка на комментарий

Учитывая, что любому приложению ОС выделяет определенные ресурсы (в том числе и объем ОЗУ), и приложения распределяют полученные ресурсы как задумали программисты, написавшие приложения - размер строк/таблиц/... определяется объемом выделенной приложением памяти для хранения/обработки подобных переменных ...

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Есть таблица вида:

 tbl = {
        text = ...,
        ...
         }

 

Тоесть не с числовыми индексами, как можно определить, что таблица не пустая, кроме как делать перебор вида for k,v in pairs()

Для таблиц с числовыми индексами есть table.getn, а как с этими быть? Вроде бы getn возвращает 0. (я правда #tbl так проверял, но это эквивалентно вроде)

 

Ну и ещё вопросец, возникла необходимость перебирать с большой скоростью (несколько раз в секунду) довольно большую таблицу (около 200 элементов). Таблица с нечисловыми индексами. Перебор делаю через pairs(), если я переделаю таблицу на числовые индексы и буду делать перебор по for i=1, #tbl do, она будет заметно быстрее перебираться? Или перебор таблицы сам по себе не особо много процессорного времени использует?

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

Ссылка на комментарий
Есть таблица вида:

Тоесть не с числовыми индексами, как можно определить, что таблица не пустая, кроме как делать перебор вида for k,v in pairs()

Для таблиц с числовыми индексами есть table.getn, а как с этими быть? Вроде бы getn возвращает 0. (я правда #tbl так проверял, но это эквивалентно вроде)

А ты вообще по текстовым индексам-то к таблице обращаешься? а то может они тебе и не нужны.

 

Ну и ещё вопросец, возникла необходимость перебирать с большой скоростью (несколько раз в секунду) довольно большую таблицу (около 200 элементов). Таблица с нечисловыми индексами. Перебор делаю через pairs(), если я переделаю таблицу на числовые индексы и буду делать перебор по for i=1, #tbl do, она будет заметно быстрее перебираться? Или перебор таблицы сам по себе не особо много процессорного времени использует?

Пока сам не проверишь никто не скажет :) Пустые циклы for i=1, #tbl do быстрее pairs() аж на 30%. Выше же в теме приводили сравнение вроде и в разработке солянки тоже подобные вещи проскакивали. А если в цикле запрашивать те же серверные объекты, или вычисления какие делать, то может на процент, два будет быстрее.

Ссылка на комментарий

> А ты вообще по текстовым индексам-то к таблице обращаешься? а то может они тебе и не нужны.

Ну текстовые индексы я привёл для примера, просто обычно я использую в качестве индекса не порядковый номер в таблице а какое то имя или id-шку объекта. И вот сегодня был момент, когда надо убедится в том, что таблица пустая, в принципе мне это уже не нужно, но знать та хочется :)

 

> Пустые циклы for i=1, #tbl do быстрее pairs() аж на 30%

Спасибо :)

Надо попробовать. Хотя я щас провёл вот тест на пустом цикле с моими двустами объектами, через profiler_timer(), цикл с pairs() отнимал около 6-7 ... тактов (?) тоесть польза 30% ускорения по мне сомнительна, но заюзать можно вполне.

Изменено пользователем *Shoker*

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

Ссылка на комментарий

*Shoker*

Стандартный способ проверки "пуста ли таблица?" :

local t={}
if next(t) then -- не пуста
...
-- или же
if not next(t) then -- пуста

Изменено пользователем Gun12
Ссылка на комментарий

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

В частности хочу показать использование функции debug.setmetatable.

Начну несколько издалека, с функции глобального окружения setmetatable и типа данных "строка".

Как известно, для строк изначально уже установлена метатаблица. В этой метатаблице находится поле __index со ссылкой на таблицу table.

Это позволяет использовать функции таблицы table как методы в ООП.

Например поиск части слова стандартным способом выглядит так :

local s = 'abcd'
local p = string.match(s,'bc')

А в стиле ООП так :

local s = 'abcd'
local p = s:match('bc')

Или же, как вариант :

local p = ('abcd'):match('bc')

Немного отвлекусь.

Методы метатаблицы строк выглядят несколько скудновато. Добавлю несколько возможностей.

1. Обращение к символу строки, как к элементу массива :

MetaString = getmetatable("")
MetaString.__index = function(str, i)
    return tonumber(i) and string.sub(str, i, i) or function(...) return string[i](...) end
end

s = 'abcdef'
print(s[3]) -- c

При этом функция после or позволит не нарушать стандартные методы.

2. Сложение строк :

MetaString.__add = function(str1, str2) return str1 .. str2 end
print('string1' + ' ' + 'string2')

3. Умножение строк :

MetaString.__mul = string.rep
print(s * 3) -- abcdefabcdefabcdef

Ну и т.д.

 

Почему бы такое не сделать, например, для чисел? Делаем.

MetaNumber = {__index = math}
debug.setmetatable(0,  MetaNumber)

local n = 100
print(n:sqrt())

Всего-то . Теперь, кроме __index, можно добавлять и другие методы.

 

А теперь по-интереснее.

Частенько при обращениях вроде obj.property не оказывается объекта obj. Или же при конкатенации какое-то (какие-то) значение оказывается равно nil. Это приводит только к одному - к ошибке (вылету).

Давайте защитимся от этого.

Создадим метатаблицу с (к примеру) парочкой методов для типа "nil" :

debug.setmetatable(nil, {__index = function() end, __concat = function(a, b) return a or b end})

print(s .. any == s) -- true

if obj.property then -- nil, если даже obj == nil, но не вылет!
    --
end

Вот пока и всё. Дальше по ходу дела.

 

 

Ссылка на комментарий

А что за тип данных в сталкере - "thread"? Сейчас заметил его в описании возвращаемых строк функции type

Freedom

Ссылка на комментарий

Desertir

Можно конечно и так, как ты указал. Главное знать ЧТО ИМЕННО нужно. Написание кода не допускает неоднозначности.

Я специально дал пример с repeat (не for и не while), чтобы напомнить о "забытых" путях.

 

Но главное даже не в стиле составления цикла. Я попытался показать несколько путей оптимизации "на лету":

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

2. Цикл прерывается при первом же "неподходящем" значении (опять же в отличии от твоего варианта)

3. Создание функции позволяет использовать код в дальнейшем.

 

 

 

 

Добавлено через 31 мин.:

А что за тип данных в сталкере - "thread"?
Вот тут я писал кой чего...

 

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    Ни один зарегистрированный пользователь не просматривает эту страницу.

AMK-Team.ru

×
×
  • Создать...