`
hulianwang2014
  • 浏览: 689696 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

Lua基础 表达式

 
阅读更多

在Lua中,表达式包括:数值常量、字符串字面值、变量、单目和双目运算符,函数调用,也包括一些非传统的函数定义和表结构。


1.算术运算符

Lua支持常规的算术运算符:'+', '-', '*', '/', '^', '%', '-'(负)。所有这些运算符都对实数起作用。举个例子,x^0.5, 计算x的平方根, x^(-1/3),计算x的立方根的反数。


在Lua中,'%'运算符定义规则如下:

a%b == a - floor(a/b)*b

对整型参数来说,它表示常规的意义,结果跟第二个参数b符号相同。

对实数来说,它有一些额外的用途。例如,x%1 表示x的小数部分,x-x%1 表示x的整数部分。类似的,x-x%0.01 将x精确到小数点后2位。



2.关系操作符

Lua提供了如下关系操作符:

< > <= >= == ~=

所有这些操作符产生的结果都是true或者false


'=='检查是否相等,'~='检查是否不等。这两个操作符可以作用于任意的两个值。如果要比较的两个值是不同的类型,那么Lua认为它们是不等的。否则,Lua根据它们的类型来比较它们是否相等。特例,nil只等于它本身。


Lua根据引用来比较table, userdata, function,也就是说,只有二者是同一个对象的时候,它们才相等。例如:

a = {}; a.x = 1; a.y = 0
b = {}; b.x = 1; b.y = 0
c = a
执行下上面的代码,你可以得到, a == c, 但是 a ~= b



我们把<, >, <=, >=称为order operator。

order operator只能应用于数值和字符串。Lua根据字母表顺序来比较字符串的大小,字母表的顺序由本地设置决定。非数值和字符串的值只能比较相等或者不相等,不能用于order operator。


当比较两个不同类型的值时,一定要小心:记住"0"和0是不同的。除此以外,2<15显然是true的,但是"2"<"15"是false的(根据字母表顺序比较)。为了避免不一致的结果,当你将string和number混合使用到order operator时,例如 2<"15",Lua会产生一个runtime error。



3.逻辑运算符

逻辑运算符有:and, or, not。跟控制结构(if,while等)类似,所有的逻辑操作符把false和nil认为是false,其他的任意值都为true。

and:如果第一个参数为false,返回第一个参数,否则返回第二个参数。

or :如果第一个参数为false,返回第二个参数,否则返回第一个参数。

print(4 and 5)              ----> 5
print(nil and 13)           ----> nil
print(false and 13)         ----> false
print(4 or 5)               ----> 4
print(false or 5)           ----> 5

'and'和'or'都是用short-cut计算方式,也即是说,只有在有需要的时候,才会去计算第二个参数的值。这样保证了类似(type(v)=="table" and v.tag=="h1")这样的表达式不会产生run-time error。(当v不是table类型时,Lua不会去计算v.tag的值)。


有用的Lua表达式:x = x or v,等价于:

if not x then x = v end

(加上x没有被赋值为false),如果x没有被设置,那么给它个默认值v。


另一个有用的Lua表达式:a and b or c,等价于C表达式 a ? b : c,(假设b不为false)。例如,我们可以用下面的语句来得到x和y的最大值。

max = (x >y) and x or y

当 x>y,第一个and表达式结果为第二个参数x,x总是true(因为x为一个数值),那么or表达式的结果为x or y,结果为x。

当 x<y,第一个and表达式的结果为false,那么or表达式的值就为false or y,结果为y。


'not'操作符总是返回true或者false

print(not nil)             --> true
print(not false)           --> true
print(not 0)               --> false
print(not not nil)         --> false

4.连接操作符

Lua用'..'(两个点)来表示string连接符。如果它的任一个操作数为数字,Lua会把它转为string。

print("Hello " .. "World")  --> Hello World
print(0 .. 1)               --> 01
不要忘了,Lua中的string是常量。string连接操作符会创建一个新的string,不会对它的操作数有任何修改

a = "Hello"
print(a .. " World")   --> Hello World
print(a)               --> Hello


5.优先级

Lua中的操作符优先级,如下表所示,从高到低

^
not    #    -(单目)
*      /    %
+      -
..
<      >    <=    >=    ~=    ==
and
or
除了'^和'..',所有的双目操作符都是左关联的。因此,下表中,左面的表达式和右面的表达式是等价的

a+i < b/2+1     <-->    (a+i) < ((b/2)+1)
5+x^2*8         <-->     5+((x^2)*8)
a<y and y<=z    <-->    (a<y) and (y<=z)
-x^2            <-->     -(x^2)
x^y^z           <-->     x^(y^z)
在有疑问的时候,就用括号'()',这比查手册更方便和简单,而且,当你以后看代码的时候,你可能仍然有同样的疑问,显式地使用括号'()'会更直观一点


6.表构造函数

构造函数是一个用来初始化表(table)的表达式。它是Lua的一个独特特性和很强大的功能之一。


最简单的构造函数是空构造函数,{},创建一个空table。构造函数也可以初始化数组,例如:

days = {"Sunday", "Monday", "Tuesday", "Wednesday", 
        "Thursday", "Friday", "Saturday"}

将day[1]初始化为"Sunday", day[2]为"Monday",注意,index是从1开始
print(day[4])      --> Wednesday
Lua提供一个专门的语法去初始化record-like table,如下:

a = {x=10, y=20}
等价于

a = {}, a.x = 10; a.y = 20
不管我们用什么构造函数去创建一个table,我们都可以增加或减少结果中的field:

w = {x=0, y=0, label="console"}
x = {math.sin(0), math.sin(1), math.sin(2)}
w[1] = "another filed"   -- add key 1 to table 'w'
x.f = w                  -- add key 'f' to table 'x'
print(w["x"])            --> 0
print(w[1])              --> another field
print(x.f[1])            --> another field
w.x = nil                -- remove field 'x'
也就是说,table创建过程是相同的。构造函数只是将其初始化而已。


Lua每次使用构造函数,都会创建并初始化一个新的table。因此,我们可以用table来实现一个list:

list = nil
for line in io.lines() do
    list = {next=list, value=line}
end
这些代码从stdin读入行,然后存入一个list中,顺序跟读入的顺序相反。list中的每个node有两个field:value,包含行的内容,next,指向下一个node。下面的代码遍历这个list,并且打印它的内容:

local l = list
while l do
    print(l.value)
    l = l.next
end

以上两段代码的示例:


(由于我们在栈上实现了list,打印的时候会是逆序的)。尽管实现很方便,但是我们在Lua程序中很少使用如上实现的list;List可以作为array得到更好的实现,我们会在后面再讲这个问题。


我们可在一个构造函数中同时使用record-style和list_style的初始化方式:

polyline = {color="blue", thickness=2, npoints=4,
      {x=0,  y=0},
      {x=-10, y=0},
      {x=-10, y=1},
      {x=0,  y=1}
     }
上面的例子也说明了如何使用嵌套的构造函数来表示更复杂的数据结构。每一个polyline[i]都是一个table,表示一条记录(record):

print(polyline[2].x)   --> -10  --此处要注意index 1是从哪里开始的,下面的示例may be helpful
print(polyline[4].y)   --> 1


这两种形式的构造函数(record-style和list_style)都有一些局限性。一些负数或者string不能作为标识符。


因此,Lua提供了一种更通用的格式。在这个格式中,我们显式的写出每一个[index]。

opnames = {["+"] = "add", ["-"] = "sub", 
           ["*"] = "mul", ["/"] = "div"}

i = 20; s = "-"
a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}

print(opnames[s])   --> sub
print(a[22])        --> ---

这个规则有点麻烦,但是更方便灵活:record-style和list_style是这个通用格式的两个特例而已。

{x=0, y=0}         <==>    {["x"]=0, ["y"]=0}
{"r", "g", "b"}    <==>    {[1]="r", [2]="g", [3]="b"}

有时候,你想要你的array的index从0开始(Lua默认从1开始),用下面的方式就可以了:

days = {[0]="Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

现在,第一个值"Sunday", index为0 。它不会影响其他的field;"Monday"的index为1,因为它是构造函数中的第一个list值;其他的跟随。尽管实现很便利,但是不推荐这样用。Lua的很多内置函数都假设array的index从1开始,如果一个array从0开始,可能会在处理上有问题。


在最后一个元素后面,可以加逗号','。这个末尾的逗号','是可选的,但都是合法的:

a = {[1]="red", [2]="green", [3]="blue",}

通过这个便利性,程序在生成Lua table的时候不需要对最后一个元素做特殊处理。


最后,我们可以使用分号';'来代替逗号',',你可以在用';'来分割table中的不同属性的部分,例如:

{x=10, y=45; "one", "two", "three"}


水平有限,如果有朋友发现错误,欢迎留言交流。



分享到:
评论

相关推荐

    Lua中文教程(pdf版)

    第3章表达式..13 3.1 算术运算符...............13 3.2 关系运算符...............13 3.3 逻辑运算符...............13 3.4 连接运算符...............14 3.5 优先级.....15 3.6表的构造..15 第4章基本语法.....

    Lua中基本的数据类型、表达式与流程控制语句讲解

    主要介绍了Lua中基本的数据类型、表达式与流程控制语句讲解,总结了Lua入门学习中的基础语法知识,需要的朋友可以参考下

    lua 程序设计学习.doc 版

    第3章 表达式 3.1 算术运算符 3.2 关系运算符 3.3 逻辑运算符 3.4 连接运算符 3.5 优先级 3.6 表的构造 第4章 基本语法 4.1 赋值语句 4.2 局部变量与代码块(block) 4.3 控制结构语句 4.4 break和return语句 第5章 ...

    WEB开发各种CHM手册

    JavaScript 基础教程.chm DOS 教材 CHM.CHM apachemenu_zh_cn.chm CodeIgniter中文手册.CHM lua-5.1中文手册.chm 正则表达式系统教程.chm php5.chm Vim手册中文版7.2.chm ThinkPHP表单令牌设计.chm PHP设计模式...

    Script.NET脚本语言开发平台

    此处下载的是基础运行平台,要使用某种脚本语言的开发功能,可以到蓝蚂蚁工作室网站下载相应语言的开发包,下载地址: http://www.blueantstudio.net/scriptnet/download/download.htm&lt;br&gt;&lt;br&gt;Script.NET主要功能...

    parse-it:Emacs Lisp中的基本解析器

    这是一个正则表达式基础分析器。 该项目的目标是生成用于定位编程语言的AST。 支持的语言 动作actionscript - actionscript 汇编语言asm Ç - c C ++- c++ C# csharp CSS- css Emacs Lisp- elisp 去- go ...

    Notepad2-mod 4.2.25.954 中文绿色版

    基础的正则表达式查找与替换 便捷的快捷键 矩形选择文本(Alt+鼠标左键) 括号配对、自动缩进、长行标记、文本缩放功能 支持多种编码,包括 Unicode、UTF-8、Unix、Mac 文本 支持添加书签 自动完成 增强的NFO字符画...

    libmarpa-bindings:基于libffi和Kollos的libmarpa绑定

    -和基础的绑定 -一个ANSI C库,它实现(“ ”, )。 地位 利巴马 如所述,由make dists构建的(源代码)。 a 可以通过luajit FFI库从Lua调用libmarpa C函数(并进行错误检查)。 样本 ,主要是带有libmarpa绑定...

    TinyCompiler:TinyCompiler是一款能编译一个经过裁剪的C语言的子的简易编译器,采用了C++11编写

    ####词法说明:在C98的基础上 1.不支持声明语句,只支持定义语句 2.不支持科学计数法 3.不支持数字加前后缀和八进制、十六进制表示法 4.字符串中不支持转义 5.无三元表达式 #####词法测试代码(选择了lua源码中的...

    像计算机科学家一样思考Python(第2版).pdf

    这是一本实用的学习指南,适合没有Python编程经验的程序员阅读,也适合高中或大学的学生、Python爱好者及需要了解编程基础的人阅读。对于首次接触程序设计的人来说,是一本不可多得的佳作。 作者简介 · · · · ...

    SubEthaEdit-5.1.3.zip 可以写文章,代码,笔记

    强大的荧光笔基于状态,正则表达式和纯文本字符串。模式可以相互引用,因此HTML模式具有全功能的CSS和javascript部分。 语法样式 这些模式引用样式的语义层次结构,可以对其进行自定义以匹配您的首选项。 自动...

    xmljava系统源码-jstarcraft-tutorial:一套涵盖核心编程,人工智能,数字图像处理,自然语言处理,推荐与搜索,云服务领域

    目标是提供一个通用的Java核心编程框架,作为搭建其它框架或者项目的基础. 让相关领域的研发人员能够专注高层设计而不用关注底层实现. 涵盖了缓存,存储,编解码,资源,脚本,监控,通讯,事件,事务9个方面. 日期 变更记录 ...

    Cocos2D-X游戏开发技术精解

    12.4.2 表达式 320 12.4.3 语句 322 12.4.4 函数 326 12.5 Lua在引擎中的应用 328 12.5.1 Lua与C/C++ 328 12.5.2 引擎中的脚本引擎 329 12.6 样例程序 331 12.6.1 脚本引擎初始化 332 12.6.2 游戏内容的实现脚本 333...

    单点登录源码

    微信公众号管理平台,除实现官网后台自动回复、菜单管理、素材管理、用户管理、消息群发等基础功能外,还有二维码推广、营销活动、微网站、会员卡、优惠券等。 &gt; zheng-wechat-app 微信小程序后台 ## 环境搭建...

Global site tag (gtag.js) - Google Analytics