Видео смотреть бесплатно

Смотреть красотки видео

Официальный сайт osinform 24/7/365

Смотреть видео бесплатно

kstep 25.02.2011 03:45

CodingВведение в Lua для начинающих программистов — часть 2

Часть 1. А это продолжение.

В этой части я расскажу о типах данных в Lua и основных операциях с ними.


Как я уже упоминал ранее, Lua — язык с динамической слабой типизацией. Это означает, что все переменные создаются на лету при первом присваивании им некоторого значения их тип опрделяется тем значением, которое им присваивается, более того, типы приводятся один к другому неявно (хотя при необходимости можно сделать явное привидение типов, но это нужно гораздо реже, чем в других языках).

Типы данных в Lua бывают следующие:

nil,number,string,boolean,function,table,userdata,thread.

Теперь подробнее о каждом из них.

Сага о пустоте

Про nil мы уже говорили раньше. Единственной контантой типа nil является... nil. Единственный смысл существования этого типа — быть непохожим на все другие. Все переменные, которые не были созданы через присваивание, при обращении на чтение считаются равными nil, поэтому не пугайтесь, если при попытке сложить переменную n с числом, скажем, 10, вы получите сообщение об ошибке вроде такого:

1
2
3
4
5
6
7
$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print(n+10)
stdin:1: attempt to perform arithmetic on global 'n' (a nil value)
stack traceback:
stdin:1: in main chunk
<c>: ?</c>



Это означает всего навсего, что вы забыли эту переменную объявить, а для типа nil не определены никакие операции. Значение nil в булевом контексте означает ложь, как я уже говорил раньше, но это не все его свойства. nil равен только nil и больше ничему:

1
2
3
4
5
6
7
8
&gt; print(n, m)
nil nil
&gt; print(n==m)
true
&gt; print(n==0)
false
&gt; print(n==nil)
true



Можете думать о нём, как о нирване: nil — это состояние полного спокойствия и пустоты.

Наполняем соcуд данными

Пустота — это хорошо, но не всегда только ей можно обойтись =)

Числа и строки представлены типами number и string.

Да, в Lua нет целого зоопарка числовых типов, вся эта сложность сокрыта от глаз простых смертных. Внутреннее машинное представление числа меняется в зависимости от контекста, динамически превращаясь то в благой integer, то в лицемерный float, но мы всего этого не увидим. Арифметически операции с числами стандартны: умножение (*), деление (/), сложение (+), вычитание (-) и возведение в степень (^). Кроме того целочисленные литералы могут записываться в шестнадцетиричном виде с префиксом 0x (например 0x10 == 16), а числа с плавающей точкой в научной нотации с мантиссой и экспоненой (10e5 == 100000, 5e-2 == 0.05) прямо как в C.

Строки текста записываются либо в одинарных, либо в двойных кавычках, либо через специальные литеральные скобки << и >>, которые питонщики могут сравнить с синтаксисом «длинных строк» с тройными кавычками """, а перловики — с HEREDOC. Так что можно писать такие строковые литералы:

1
2
3
4
5
6
7
8
very_long_string_1 = <<
Эта строка содержит несколько переводов строки,
но не может содержать двух квадрадных скобок подряд.
>>
very_long_string_2 = <=<
Зато это строка может содержать символы >> совершенно свободно.
Вот!
>=>



То есть между двумя открывающими и закрывающими литерал квадратными скобками может быть любое число знаков равно, от нуля до бесконечности, лишь бы это число совпадало у закрывающей и открывающей пары скобок, так что можно один Lua код класть в литерал другого Lua кода совершенно безопасно (если придерживаться некого соглашения о числе знаков равно в этой конструкции =).

Кроме того строки в Lua совершенно Unicode-безопасны, так что пусть у вас об этом голова не болит.

Приведение типов между number и string происходит совершенно неявно и полностью зависит от контекста, что сразу должны понять и оценить перловики:

1
2
3
4
5
6
&gt; print("5" + "6")
11
&gt; print("5" + 6, 5 + "6")
11 11
&gt; print(5 .. 6)
56



Такая вот своеобразная магия Lua.

Условности этого мира

Булев тип в Lua называется (вы таки не поверите) boolean. В языке есть две встроенных константы этого типа: true и false, и, соответственно, это единственные значения, которые может принимать переменная типа boolean. Казалось бы тут и закончить мой рассказ, но это ещё не всё. Здесь я хочу рассказать про булевы выражения в Lua.

С арифметическим сравнением всё просто: «==» — равно, «~=» — не равно, «<» и «>» — меньше и больше, «<=» и «>=» — меньше либо равно и больше либо равно. Однако эти операции, при кажущейся простоте, не всегда кристально прозачны.

Для чисел они очевидны, для строк они проводят лексическое сравнение (то есть, например, "A" < "a", a "b" < "bb"), но если сравнить две переменных (или литерала) разных типов, то мы получим нечто не совсем ожиданное, а именно "10" == 10 совсем не истинно, а даже очень и очень ложно.

Почему так? Потому что операции сравнения не приводят типы неявно, как арифметические оперторы и оператор конкатенации, они сперва сравнивают типы двух сравниваемых величин, и если эти типы различны, то результат будет false, и плевать на содержимое. Для более сложных типов (всех, кроме nil, number, string и boolean) операции сравнения сравнивают типы и ссылки на объекты (а точнее адреса, по которым эти объекты размещены в памяти), поэтому если сравнить две переменные с типом table, то они окажутся равными только если ссылаются на одну и ту же таблицу.

Весь предыдущий абзац истинен только для оперций равенства и неравенства (== и ~=), все остальные операции сравнения имеют смысл только для типов string и number, при этом типы операндов сравниваемых значений должны быть идентичны, иначе опять будет ошибко.

Покажем на примере:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
&gt; print("a"=="a")
true
&gt; print(10=="10")
false
&gt; function a() end function b() end
print(a==b) -- это два разных объекта типа «функция» с разными адресами
false
&gt; a=b -- присвоим ссылку на функцию b переменной a
&gt; print(a==b) -- теперь они равны, т.к. указывают на одну и ту же функцию по одному и тому же адресу
true
&gt; print(10&gt;nil)
stdin:1: attempt to compare nil with number
stack traceback:
stdin:1: in main chunk
<c>: ?
&gt; print(a&gt;b)
stdin:1: attempt to compare two function values
stack traceback:
stdin:1: in main chunk
</c><c>: ?
&gt; print("10"&lt;5)
stdin:1: attempt to compare string with number
stack traceback:
stdin:1: in main chunk
</c><c>: ?</c>



Так что же делать, если нам надо таки сравнить число со строкой? Тут нам и понадобиться явное приведение типов, и для этого в Lua есть целых две встроенных функции! Встречайте: tonumber() и tostring(). Первая пытается из некого объекта выжать число, а если не получится, то возвращает nil, вторая же возвращает строку, при этом если это некий сложный тип данных, вроде функции, то вернётся символьное представление этого значения. Теперь мы можем делать так:

1
2
3
4
5
6
7
&gt; print(tonumber("10")&lt;5)
false
&gt; print("10"&lt;tostring(5))
true
&gt; function a() end function b() end
&gt; print(tostring(a)&gt;tostring(b))
false



И нас никто не остановит. Муа-ха-ха!

В последнем выражении я не знаю, что у вас получится, потому что символьное представление функций a и b у вас может быть совершенно произвольное, ведь это по сути адрес в памяти в шестнадцетиричном виде:

1
2
3
4
&gt; print(tostring(a))
function: 0x9b11850
&gt; print(tostring(b))
function: 0x9b118f0



Ну и напоследок о булевых операциях: логические и, или и не записываются как and, or и not. Исключающего или нет, как его сделать представляю в качестве упражения читателям (там достаточно универского курса мат. логики... ну или почитать книжку).

Все бинарные логические опреации в Lua являются «короткими», то есть в выражении A and B B будет вычислено только если истинно A, а в выражении A or B B будет вычислено только если A ложно. Более того, эти операции возвращают не строго значения true или false, а последнее вычисленное. То есть комбинацией and и or можно до некоторой степени сэмулирвать тернарный оператор, отсутствующий в Lua:

1
2
3
4
5
6
a = 10
b = 20
--<=<
Аналог "c? a: b" в C/Perl или "a if c else b" в Python
>=>
print(a == b and a .. b or a + b)



Обращаю внимание, также, что приоритет логических операций ниже, чем арифметических, поэтому здесь скобки не нужны. А ещё внимательный читатель должен обратить внимание на мою ремарку «сэмурировать до некоторой степени», а вот до какой степени... Считайте это ещё одним заданием на дом =)

На закуску...

я оставлю рассмотрение типов table, thread, function и userdata. Точнее перенесу их рассмотрение в следующую статью. Я честно хотел рассказать обо всех типах данных в одной статье, но вижу, что уже выложил очень много материала, и нужно дать время на его усвоение, поэтому на этом месте я прервусь.

Итог:

Мы рассмотрели простые типы данных nil, number, string и boolean, их запись (включая числа в шестнадцетиричном и научном видах, а строки в двойных квадратных скобках), основные операции с ними, познакомились с явным и неявным приведением типов и особенностями сравнения значений в Lua. А ещё те, кто умеет читать внимательно, научился писать однострочные и многострочные комментарии =)

В следующей статье я расскажу про остальные более сложные типы данных и основных операциях с ними.


Тэги: lua luaintro программирование
+ 17 -
Похожие Поделиться

kstep 25.02.2011 16:32 #
+ 0 -
Да, комментарии по улучшению повествования приветствуются. Всё ли понятно, что нужно изменить-дополнить, про что стоит рассказать дополнительно?
philosoft 25.02.2011 16:52 #
+ 1 -
метатейблы!11 ?
kstep 25.02.2011 18:22 #
+ 0 -
Про них я думал рассказать попозже, после того как закончу с основными типами данных, а то рассказывать про них не введя понятия таблицы и лямбда-функции как-то глупо.
philosoft 25.02.2011 20:13 #
+ 1 -
Я просто их в планах к первой статье не заметил.
GalS 25.02.2011 18:50 #
+ 0 -
Правильно ли я понял, что == и ~=, аналоги "строгих" сравнений в некоторых других языках(=== и !==)?

PS
> a=b -- присвоим по ссылку на функцию b переменной a

kstep 25.02.2011 19:13 #
+ 0 -
Фактически да. Они всегда сначала сравнивают типы, а содержимое сравнивается только при равенстве типов.
kstep 25.02.2011 19:14 #
+ 0 -
Я здесь правда немного лукавлю, так как при использовании некоторой особой лунной магии можно переопределить операции сравнения для конкретного объекта, но в обычной ситуации так и есть.
K900 25.02.2011 19:27 #
+ 1 -
Реквестирую примеры реального использования части где-нибудь к пятой :)

В хорошем качестве hd видео

Онлайн видео бесплатно


Смотреть русское с разговорами видео

Online video HD

Видео скачать на телефон

Русские фильмы бесплатно

Full HD video online

Смотреть видео онлайн

Смотреть HD видео бесплатно

School смотреть онлайн