lua学习笔记之-语言基础

一、基本知识

1.第一个程序:

print("hello lua");

在交互模式下直接运行:

> print("hello lua")

hello lua --输出

保存在文件中运行:

$ lua hello.lua

hello lua --输出

2.chunks:

* 定义:trunks指运行的语句块,一个文件,一个函数或是运行模式下每行语句、语句组合都是trunks;

* 语句之间的分割府(";")可有可无,为了可看性可维护性一般加“;”分割。

* 交互模式运行trunks:

Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio

>

a)交互模式键入的每行语句立即执行,不是完整的trunks时提示符为“>>”提示继续输入直至语句完整,交互模式可键入文件结束符(Ctrl-D in Unix, Ctrl-Z in DOS/Windows),或是调用OS库的os.exit()退出;

b)通过指定参数运行lua的一系列trunks,如一个文件a.lua有语句x = 1,文件b.lua有语句print(x),则在命令行调用>lua -la -lb 则输出“1”。此命令首先运行a,再运行b(-l命令会调用require),使用-i选项运行完trunks语句后进入交互模式;

c)使用dofile加载外部trunk。如:

文件:

ubuntu$ cat ext.lua

function ext_trunk()

print("external trunks")

end

运行:

Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio

> dofile("ext.lua")

> ext_trunk()

external trunks

>

* 全局变量不需要声明,给出一个变量赋值后即创建变量。未初始化的全局变量值为nil,删除变量只需把值设置成nil:

print(b) --> nil

b = 10

print(b) --> 10

* 词法约定:

a)标识符:字母或者下划线开头的字母、下划线、数字序列(由于lua保留子也是下划线开头所以最好不要使用下划线开头标识符);

b)保留字(lua大小写敏感):

and break do else elseif end false for function if in local nil not or repeat return then true until while

c)lua注释:单行注释用“--”,多行注释用:--[[ --]];

* 命令行方式:lua [options] [script [args]]

a)-e :将命令直接传入(如:lua -e "print(math.sin(12))" --> -0.53657291800043);

b)-l:加载一个文件;

c)-i:进入交互模式;

d)通过_PROMPT内置变量存放交互模式的提示符

dht$lua -i -e "_PROMPT='mylua>'"

Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio

mylua>_PROMPT="hh>"

hh>

e)lua在运行参数之前会查找环境变量LUA_INIT的值,加载指定文件或代码(实验);

f)全局变量arg存放Lua命令行参数。

二、类型与值

1.lua有 八个基本类型:nil、boolean、number、string、userdata、function、thread和table。

a)可通过type函数获取变量或值的类型字符串。如:

print(type("Hello lua")) --> string

print(type(10.4*3)) --> number

print(type(print)) --> function

b)变量没有预定义类型,每个变量可设置成任意一种类型,函数也可以像变量一样使用.如:

print(type(a)) --> nil

a = 10

print(type(a)) --> number

a = "a string!!"

print(type(a)) --> string

a = print

print(type(a)) --> function

2. nil:特殊类型,只有一个值nil,全局变量赋值以前值为nil,删除一个全局变量只需把变量赋值为nil;

3. boolean:只有true和false两个值,在控制语句中除了false和nil为假,其余值都是真,如0和空串都是真;

4. number:表示实数,lua没有整数;

5. string:字符序列,lua为8位字节,字符串可以包含任何数值字符

a)string进行自动内存分配和释放;

b)lua支持的转义序列列表:

\a bell

\b back space -- 后退

\f form feed -- 换页

\n newline -- 换行

\r carriage return -- 回车

\t horizontal tab -- 制表

\v vertical tab

\\ backslash -- "\"

\" double quote -- 双引号

\' single quote -- 单引号

\[ left square bracket -- 左中括号

\] right square bracket -- 右中括号

c)字符串中还可以用\ddd表示字母,如:"alo\n123\""和'\97lo\10\04923"'是相同的

> print("alo\n123\"")

alo123"

> print('\97lo\10\04923"')

alo123"

>

d)用[[...]]表示字符串,可以包含多行,第一个字符是换行会被自动忽略。如:

> page = [[

>> <HTML>

>> <TITLE> An HTML Page</TITLE>

>> "this is a string'

>> </HTML>

>> ]]

> print(page)

<HTML>

<TITLE> An HTML Page</TITLE>

"this is a string'

</HTML>

>

e)lua会自动在string和numbers之间自动进行类型转换:

> print("10" + 1)

11

> print("10 + 1")

10 + 1

> print("-10" * "2")

-20

> print("hello" + 1) //出错hello不能转为数字

stdin:1: attempt to perform arithmetic on a string value

stack traceback:

stdin:1:

in main chunk

[C]: ?

> print(10 .. 20)

1020

> print(tostring(10) == "10")

true

> print(10 .. "" == "10")

true

> print(10 == "10") //虽然可以互相转换,但类型不同并不相等

false

>

6. function:函数也是一个类型,可以存储在变量中,可以作为函数参数,返回值。

7. userdata和thread后面介绍。

三、表达式

1. 算术运算符:

* 二元运算符:+ - * / ^(加减乘除幂)

* 一元运算符:- (减)

* 算术运算符操作数都是实数

2. 关系运算符:< > <= >= == ~=

* 俩值类型不同,lua认为两者不同,nil 只和自己相等:

> print(false == nil) --false和nil不相等

false

> print(x == nil)

true

>

* lua通过比较引用比较tables、userdata、functions:

> a = {}; a.x = 1; a.y = 0

> b = {}; b.x = 1; b.y = 0

> c = a

> print(a == c) --a和c互为引用

true

> print(a == b) --a和b的值完全相同,但是是不同对象

false

>

* lua比较数字按照传统数字大小,比较字符串按照字母顺序进行比较。混合比较数字和字符串会报错:

> print(2 < 15)

true

> print("2" < "15") --字符串比较字母顺序

false

> print("0" == 0) --类型不同

false

> print(2 < "15") --字符串和数字不能混合比较

stdin:1: attempt to compare number with string

stack traceback:

stdin:1: in main chunk

[C]: ?

>

3. 逻辑运算符:and or not

* 逻辑运算符认为nil和false为假,其余为真:

* and和or运算结果不是true或false:

a) a and b:如果a为false则返回a,否则返回b

> a = nil; b = 1

> print(a and b)

nil

> a = 1; b = 2

> print(a and b)

2

>

b) a or b:如果a为true返回a,否则返回b

> a = nil; b = 1

> print(a or b)

1

> a = 1; b = 2

> print(a or b)

1

>

c) and的优先级比or高

d) C语言中的a ? b : c 相当于nil中的(a and b) or c

* not只返回true或者false

> print(not nil)

true

> print(not false)

true

> print(not 0)

false

4. 连接运算符:..(两点),连接俩字符串,如果操作数为数字,则会转为字符串:

> print("hello " .. "lua")

hello lua

> print(0 .. 1)

01

>

5. 优先级(从高到低)

^

not - (unary)

* /

+ -

..

< > <= >= ~= ==

and

or

6. 表的构造:

* 最简单的构造函数:{} ,用来构造一个空表;

* 初始化一个数组(数组下标从1开始,数组元素可以是任何类型):

> arr = {"str", 10, math.sin(10)} --实际初始化的模型是这样的:arr = {[1] = "str", [2] = 10, [3] = math.sin(10)}

> print(arr[1]) --类型为字符串

str

> print(arr[2]) --类型为数字

10

> print(arr[3]) --类型为函数表达式

-0.54402111088937

* 初始化一个表:tbl = {x=1, y=2} 与 tbl = {}; tbl.x = 1; tbl.y = 2 和tbl = {['x'] = 1, ['y'] = 2}等价;

* 不管用何种方式建table,都可以向表中添加、删除任何类型的域,构造函数仅影响初始化

* 用table构造一个list:

words = {"A", "B", "C", "D"}

list = nil;

for k, v in pairs(words) do

list = {next=list, value=v}

end

l = list

while l do

print(l.value)

l = l.next

end

结果为:D B C A

* 混合使用列表和记录进行初始化:

polyline = {color="blue", {x=0, y=0}, {x=-10, y=0}}

print(polyline[2].x) --> -10

结果为:-10

* table下标一般不从0开始,很多标准库不支持。构造函数中的域可以用逗号(,)隔开,也可以用分号(;)隔开

四、基本语法

Lua 传统语句:赋值语句、控制结构语句、函数调用等,同时也支持非传统的多变量赋值、局部变量声明。

1. 赋值语句

* a = "hello " .. "lua" --单个变量赋值

* a, b = 10, 20 ---两个变量赋值相当于 b = 20; a = 10(先右边赋值再左边赋值)

* x, y = y, x --根据先右边赋值再左边赋值的特性,此代码可以交换两个变量

* 当变量个数>值个数时多余变量值为nil:

a, b = 10; print(a,b); -- 结果为10 nil

* 变量个数<值个数时多余的值被忽略

a, b = 10, 20, 30; print(a,b); ---结果为10 20

* 注意:两个变量赋值按照先右后左,但是多个变量的情况下必须从左到右依次赋值,函数返回不管多少个值都是从左到右依次赋值。

2. 局部变量与代码块

* 局部变量添加local来声明,局部变量只在声明局部变量的代码块内有效

* 在交互模式下局部变量的作用域可能和想的会有所不同,因为一行执行是个完整的chunk

> local i = 1

> print(i)

nil

>

* 利用do ... end可以更好的定义语句块,为一个chunk划分界限。do ... end相当于C中的{...}

> do

>> local i = 1

>> print(i)

>> end

1

>

3. 控制结构语句

*if语句的三种形式:

if conditions then ---1

then-part

end;

if conditions then ---2

then-part

else

else-part

end;

if conditions then ---3

then-part

elseif conditions then

elseif-part

.. --->多个 elseif

else

else-part

end;

*while 语句

while condition do

statements;

end;

*repeat-until语句

repeat

statements;

until conditions;

*for语句的两种

a) 数值for循环

for var=exp1,exp2,exp3 do loop-part end

b) 范型 for循环

for i,v in ipairs(a) do print(v) end

4. break和return语句

* break语句用于退出循环:for repeat while --循环外不可使用

* return 用来返回函数结果

* break和return只能在block的前一句,即在end,else,until之前

* 通常可以在代码中插入 do return end的方式使得return可以出现在代码块中间。