(一)lua基础语法
1.从hellowrold开始
--语法和Python比较类似,直接像Python一样使用print即可 --这里我可以直接写中文,显然被当成了注释。在lua中,两个-表示注释 --[[ 这种形式可以表示多行注释 ]] --在lua中,语句后面也可以像Python一样加分号,但也可以不加。 print("hello world")
2.lua的基本类型
--lua和Python一样,并不需要像C一样声明一个变量,因为本身带有值的类型 --直接给变量赋值即可 --[[ lua的基本类型有:nil(空) boolean(布尔) number(数字) string(字符串) table(表) 函数等内容后面再说 ]] --[[ 注意:赋值的时候,可以将多个语句写在一行,用空格或者;分隔。 这里只是演示,但是实际开发中不建议这么做 ]] a = ;b="satori";c=3.14;d=math.pi --使用type查看值的类型 print(type(a), type(b), type(c), type(d)) -- number string number number --可以看到,lua中没有什么int float等等,只要是数字,类型通通为number print(type(print)) -- function --如果一个变量我们没有赋值直接使用的话,在Python中会报错,提示name xxx is not defined --但在lua中不会报错,对于一个没有赋值的变量在lua中默认为nil --nil用于区别其他变量,给一个全局变量赋值为nil等于删除这个全局变量 print(mmp, type(mmp)) -- nil nil --在lua中,只有false和nil表示假,其他的都表示真。0和空字符串在lua中表示真,这和Python不太一样 --lua中,字符串一旦创建了,便不可以修改了。这和Python一样,但是在Python中可以使用replace修改并返回一个新的字符串 --那么lua也有类似的方法,该方法同样会得到一个返回值,不会修改原来的值 s1 = "hello cruel world" s2 = string.gsub(s1, "cruel", "beautiful") print(s1) -- hello cruel world print(s2) -- hello beautiful world --并且在lua中,可以使用单引号也可以使用双引号 --类似于Python,如果输入的字符串本身有单引号,那么外部就用双引号,反之亦然 print("I'm satori") --I'm satori --如果我非要使用相同的引号,那么可以使用转义字符,将内部的引号进行转义 print('I\'m satori') --I'm satori --[[ 一些转义字符 \a:响铃 \b:退格 \f:提供表格 \n:换行 \r:回车 \t:制表 ]] print("i am \r satori, come from \n东方地灵殿") --[[ satori, come from 东方地灵殿 ]] --字符串也可以使用\加上三位数字表示,就是相应的ascii表 print("\065") --A -- 如果想表达多行字符串,可以使用[[ ]],类似于Python中的三引号''' ''' s3 = [[ 南村萝莉欺我老无力 经常与我发生性 关系 ]] print(s3) --[[ 南村萝莉欺我老无力 经常与我发生性 关系 ]] --如果一个字符串和一个数字进行运算的话,那么会尝试将字符串转化成数字 --显然字符串必须是由数字组成,如果包含不是数字的字符,就会报错,无法转化 ) --字符串的连接,在lua中..表示字符串连接 --不可以使用"a"+"b"这样的形式,这在Python中是允许的,但在lua中不可以。但可以使用.. s4 = " satori" print("a".."b"..s4) --ab satori ") -- 1+1 == 2 -- 如果我想获取一个字符串的长度该怎么办呢?在Python中使用len函数,但在lua中使用#。 -- 而#在Python中表示注释,因此两门语言某些地方类似,某些地方又完全不同,确实很有意思 -- 输出结果为45,咦,不是15吗?肯定一眼就找出答案了,一个汉字占三个字节 -- 而且lua默认用的是utf-8编码。值得一提的是,在Python中使用len函数计算出来的结果为15 -- 因为在Python中,len计算的是字符数,而不是字节数。 -- 而且在go语言中,计算的结果也为45,同样是字节。如果想得到字符数,在go中需要用[]rune转化一下。 s6 = "mmp" -- lua中还有一种叫做table的类型,说白了就是Python中的字典(哈希表),key和value一一对应 hash_map = {} hash_map["satori"] = "东方地灵殿" print(hash_map["satori"]) -- 东方地灵殿 -- 将hash_map赋值给别的变量,并且将hash_map删除 hash_map_1 = hash_map hash_map = nil print(hash_map) -- nil print(hash_map_1["satori"]) -- 东方地灵殿 -- 可以看到即使删除了hash_map,但不会对hash_map1造成影响 -- lua的垃圾回收采用的是标记清除,当hash_map1也赋值为nil,没变量再引用的时候就会删除垃圾资源 --如果访问一个不存在的key,那么得到的会是nil x = {} x[] = x[] = ], x[], x[]) -- 2 3 nil --想删除table中某个元素,直接赋值为nil即可 x[] = nil ]) -- nil -- 而且table这种结构,还可以使用.来访问 x.name = "satori" print(x.name) -- satori
3.操作符
--1.算术操作符 a = b = print(a/b) --7.5,这里和Python3一样,不是地板除,而是会包含小数部分 --这里值得注意的是,Python中平方是**,而lua中是^ --2.关系操作符 >) -- true <) -- true >=) -- true <=) -- true ==) -- true --注意:不等于在Python中是!=,但在lua中是~= ~=) -- true --3.逻辑操作符, 这个和Python类似,有and,or,not a1 = a2 = -- 别忘了0在lua中表示真,这和Python不一样 a3 = b1 = b2 = b3 = nil or false --[[ 对于a and b,首先and表示两边都为真整体才为真。如果a为真,那么还要判断b。a为假,b就不用判断了 因此对于 a and b,结果究竟是a还是b,其实不取决于b,而是取决于a。 如果a为真,那么由于and的特性,因此还要判断b,那么结果就为b,不管b是真还是假 如果a为假,那么由于and的特性,b不需要判断了,那么结果就为a 同理对于a or b也是一样。a or b表示两边都为假整体才为假 如果a为真,那么不管b是真是假,整体都为真,所以b无需判断,结果就为a 如果a为假,那么还要判断b,因此结果就是b。 因此在lua和其他语言一样,也存在着短路求值,当第一个条件已经能够决定整体的结果时,剩下的条件就不会再判断了 举一个C语言的例子 #include <stdio.h> int main() { int a = 10; if (1<0 && a++) { printf("你猜a的值为多少?\n"); } printf("a=%d\n", a); if (1<0 || a++) { printf("你猜a的值又为多少\n"); } printf("a=%d\n", a); } 第一次打印a的时候,值为10,因为1<0为false,所以a++无序判断,因此a++根本没有执行。 第二次打印a的时候,值为11,因此1<0为false,但是操作符是or,所以会判断a++,因此if语句执行完之后打印11 ]] print(a1, a2, a3) --5 4 nil print(b1, b2, b3) --5 7 false -- 那么对于4 and 5 and nil or 4 and 5 or 7,会打印什么结果 --[[ 操作符从左往右看,4 and 5结果为5,5再and nil,结果为nil, nil 再or 4,结果为4, 4 and 5结果为5, 5 or 7结果为5 ]] ) --[[ 我们也可以用这种方式来模拟三元操作符 v = a or b,如果a为真,v=a,否则等于b v = a>b and x or y,如果a>b,结果为x。因为a>b为真,(a>b and x) == x, x又为真,那么or上y当然为x 如果a<b,结果为y。因此a<b,那么a>b为假,(a<b and x)==(a<b),一个假or上y当然为y 因此 v = a>b and x or y,就类似于C中v = a>b?x:y,类似于Python中v = x if a>b else y ]] -- not就比较简单了,表示取反 print(not false) --true ) --false print(not nil) -- true print(not "satori") --false --4.字符串的连接 --前面介绍过可以使用..连接字符串 print("宇宙には始まりはあるが".."、終わりはない".."、無限") --宇宙には始まりはあるが、終わりはない、無限 print("星にもまた始まりはあるが".."自らの力を持って滅び逝く".."有限") --星にもまた始まりはあるが自らの力を持って滅び逝く有限 -- 如果字符串和数字拼接,那么会自动将数字转化成字符串 a = print("96猫@"..a.."cm") --96猫@142cm --[[ 这里需要注意的是,我们是用a表示142,也可以直接写上142 print("96猫"..142),也是合法的,但是,我要说但是了。 如果直接写上142的话,那么后面就不能再接..了,意思就是"96猫"..142是合法的,会得到96猫142,但是142.."96猫"是非法的。 如果将这个值赋值给一个变量,a = 142,那么"96猫"..a,和a.."96猫"都是合法的 ]] --5.操作符优先级 --[[ 这个就不介绍了,跟其他语言类似。 总之一句话:如果不确定的话,那么使用括号就可以了 ]] --6.table构造式 days = {"星期一", "星期二", "星期三","星期四","星期五","星期六","星期日"} --table每一个元素是由key和value组成的,而我们这里显然不是键值对的形式 --在lua中,在不指定key的情况下,可以使用索引来指定。但是比较恶心的是,索引默认是从1开始的,这个比较反人类。 --所以days[1]便是第一个元素,days[2]是第二个元素。感觉table既有点像数组也有点像字典 ]) --星期一 ]) --星期四 ]) --星期日 --table还有一种构造形式 days = {name=, anime="东方地灵殿"} --等价于:days={}; days.name="satori"; days.age=18; days.anime="东方地灵殿" print(days.name, days.age, days["anime"]) --satori 18 东方地灵殿 --不管怎么创建,lua中的table和Python的dict一样,都可以自由动态的添加或者删除。 --添加:直接写上key value即可,删除:直接令相应key对应的value等于nil即可
4.语句
--1.赋值 --首先lua和Python一样,可以进行多重赋值 a,b=, print(a,b) --1 2 --也可以直接进行两数交换,而不需要中间变量 a,b=b,a print(a,b) --2 1 --比较特殊的一点,当左边的变量和右边的值在数量上不匹配的时候 x,y,z = , --这句代码在Python中毫无疑问会报错,但在lua中不会 --当左边的变量数多于右边的值的时候,那么得不到值得变量会被赋值为nil print(x,y,z) --1 2 nil x,y = ,, --同样这句代码在Python中也会报错,但在lua中也不会 --当左边的变量数少于右边的值的时候,多余的值会被自动丢弃 print(x,y) --1 2 --但是值最好要匹配 --2.局部变量和块 --局部变量,声明一个局部变量只需要在变量前面加上local关键字即可,局部变量只在当前的语句块里面有用 --如果不加local,在while循环中新建一个y,那么while循环结束后,打印y,会打印循环里面给y赋的值。 --因为循环里面的y是全局的,会覆盖上面的y x = y = do y = x = x+ end --但是当我加上了local,会发现打印的还是40,因为局部变量不会对全局变量造成影响 --类似于Python中的函数,在函数中定义的变量,只要不加global关键字,都是局部变量 --并且Python无法在while循环中声明一个局部变量。循环,条件语句等等,对于Python来说,只有全局变量。但lua可以。 x = y = do x = x+ end var1 = var2 = > then var2 = end --可以看到var1没被修改,var2被修改了。if里面的var1只在if里面有效,不会对外面的var1造成影响。而var2是会覆盖外面的var2的。 xxx = then print(xxx) else end --如果if条件成立,会打印666,但是不成立,会打印123. --但是如果我没在条件语句、循环等等中声明局部变量,而是在最外面声明一个局部变量呢? > then v = end --会发现这个局部变量,就等同于全局变量 --此外,我们还可以使用do end来声明一个语句块。当遇到lua解释器遇到do,会先找到对应的end,然后执行do和end里面的内容。 do end print(wanwan) -- nil --由于我声明了do end,那么do end里面的局部变量是无法在外面被检测到的,所以打印为nil。 --值得一提的是,如果不加local,那么wanwan仍旧是一个全局变量,在外面还是可以访问的到的。 --局部变量会虽着作用域的结束而消失 --3.控制结构 --if条件语句,和Python比较类似。但是需要在条件语句结束后加上end,有点像Python的tornado框架里的模板语言。 --此外if条件后面还需要加上then if false then print("古明地觉") >= then print("芙兰朵露斯卡雷特")--芙兰朵露斯卡雷特 else ") end --此外,if语句还可以嵌套 gender = 'f' age = if gender == 'f' then then print("获取我们可以做一场交易") then print("虽然担些风险,但也值得一试")-- 虽然担些风险,但也值得一试 else print("最低三年,最高死刑") end else print("oh♂yeah SIR") end --此外,连接两个条件,lua中也使用and or关键字,而不是&&和|| --循环语句 x = do print(x) x = x + --注意不可以写成x+=1的形式 --[[ 10 11 12 13 14 ]] end -- 可以想象相较于Python,把:换成了do,并且在结尾加上了end --并且在lua中还有一个repeat until,表示啥呢?从名字也能看出,重复····直到··· --不得不说,往往英语不是母语的人,发明出来的语言,关键字更清晰易懂。 x = repeat x = x+ print(x) --[[ 2 3 4 ]] --这段代码表示啥呢?不断地重复x = x+1; print(x),直到x>3为止,你再往下走 --当然lua中还有for循环 --[[ 结构: for i=a,b,c do <body> end 这几行代码是什么意思呢?转化为while循环 i=a while i<=b do <body> i = i+c end 注意:如果c不指定,默认为1 ]] ,, do print(i) end --[[ 1 4 7 10 ]] --注意:for循环里面的i,只在for里面有效。for循环结束后,就被自动销毁了。 print(i) --nil --for遍历table t = {name=, gender="f"} --和Python不一样,在lua中不能直接遍历,需要遍历pairs(table),可以只遍历key,也可以遍历key和value for k,v in pairs(t) do print(k,v) --[[ gender f name satori age 18 ]] end --如果遍历的时候,同时指定索引 --此时的t就类似于数组,可以直接使用索引访问,但是从1开始,反人类 t = {"satori", "koishi","mashiro"} ]) --satori for k,v in ipairs(t) do print(k, v) end --[[ 1 satori 2 koishi 3 mashiro ]] --查找某个值所在的位置 days = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"} for k,v in ipairs(days) do if v == "星期三" then end end --4.break和return --break,跳出所在的循环, 如果外部还有循环则不会跳出。 --return,只能出现在函数里,结束函数并返回一个值 , do then break end print(i) --[[ 1 2 ]] end --return等介绍函数的时候再说
5.函数
--如何定义一个函数 --[[ 函数结构: function foo() <body> end ]] function add(a) b = print(a+b) end add() print(b) --11,这里打印11,说明能找到add函数里面的b,明明是在函数里面,函数结束了,居然没有被销毁。 --显然不加local,即使是在函数里,外部也能访问的到。 --像os.date(),math.sin()等等都属于函数 print(os.date()) --10/18/18 14:16:38 )) --0.5 --函数的传参 function foo(a,b) print(a,b) end --这里foo函数需要指定两个参数,但如果我只指定一个会怎么样?指定三个又会怎么样 foo() --666 nil --可见没有得到值的参数会等于nil foo(,,) --666 777 --多余的值会自动丢弃,这在Python中是不允许的,该传几个就传几个 --类似于赋值a,b=1 ; x,y=1,2,3 --另一种传参方式 function foo(...) local a,b,c=... print(a,b,c) end foo(,,) -- 1 2 3 --函数的返回值,这个和Python一样,可以返回多个,比如string.find()函数 print(string.find("hello cruel world", "cruel")) -- 7 11 --这里有两个返回值,7表示cruel的开始位置,11表示cruel的结尾位置。当然索引是从1开始的,反人类。 --自己定义一个函数,接受一个数组,返回数组的最大值以及索引 function get_max_value(arr) max = arr[] ind = for index, value in ipairs(arr) do if value > max then max,ind = value,index end end return max,ind end ,,,,,,,,,})) --42423 8, 索引从1开始,反人类 --首先函数即变量,函数也是可以直接赋值的 t = {a=print} t.a("hello world") --hello world math.sin, print = print, math.sin )) --0.5 --可以看到进行交换之后,可以直接当做对方去使用。 --这里我们在交换回来,不然下面不好进行了 math.sin, print = print, math.sin function foo() return "古明地觉" end bar = foo print(bar()) --古明地觉 --匿名函数,其实说白了还是普通的函数,只是可以写在一行,并且省了函数名 --类似Python里的lambda,只建议定义一些简单的逻辑。 foo = end )) --4, --使用function还可以对table里面的元素进行排序 --table.sort函数可以对一个table进行排序 girls = { {name=}, {name=}, {name=}, } --这个函数会直接在原table上进行修改 table.sort(girls, function(a,b) return (a.name>b.name) end) for i,v in ipairs(girls) do print(v.name) --[[ satori mashiro koishi ]] end --[[ 可以看到按照name从大到小排列了,a,b就代表了table里面的所有元素。每两个进行比较,a.name大的放在前面。 再比如Python: girls = [ {"name":"satori", "age":18}, {"name":"koishi", "age":17}, {"name":"mashiro", "age":16} ] girls.sort(key=lambda x: x["name"]) 这个x就代表了girls里面的每一个元素,怎么排,按照x["name"]来排,这个默认是从小到大排 ]] --关于排序,还可以按照table去排序其他table,怎么理解呢? girls = {"mashiro", "satori", "koishi"} age = {mashiro=, satori=, koishi=} --此时girls和age一一对应,我想age从小到大的方式排序girls table.sort(girls, function (a,b) return age[a]<age[b] end) ], girls[], girls[]) --mashiro koishi satori --计算导数 --导数公式,(f(x+d) - f(x)) / d ,这个d趋近于无穷小 function derivative(f, delta) delta = delta or 1e-4 --这算是缺省参数,如果我们不指定,那么delta为nil和1e-4进行or运算,会等于1e-4 return function(x) return (f(x+delta) - f(x)) / delta end end --这里使用了闭包,闭包就是函数内部还嵌套一个函数,并且内部嵌套的函数,要引用外部函数的变量 foo = derivative(math.sin, 1e-5) )) -- -0.83906880893325, 便是函数math.sin在x=10处的导数 function newCounter() return function() i = i+ print(i) end end --内部的i是可以访问到外部的i的 f = newCounter() --此时的f就是闭包里面的那个函数 --显然这个i并没有被销毁,因为在外部有f指向内部的函数,因此没调用一次,i就会加1,这和go语言基本上一样 --和Python也有点相似,只不过Python中需要nonlocal关键字声明 f() f() f() --函数递归,最经典的便是阶乘 function fac(x) then end ) end )) ********)
(一)lua基础语法的更多相关文章
- Lua基础语法讲解
Lua 是什么? Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学( ...
- Lua - 基础语法
Hello World 交互式编程 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用: [huey@huey-K42JE lua]$ lua Lua 5.1.4 Copyright ...
- lua——基础语法
-- test lua: for learning lua grammar -- line comment --[[ block comment ]]-- -- print hello world p ...
- Nginx详解二十二:Nginx深度学习篇之Lua解释器安装及基础语法
解释器 Lua:Lua是一个简洁.轻量.可扩展的脚本语言 Nginx+Lua优势充分的结合Nginx的并发处理epoll优势的Lua的轻量实现简单的功能切高并发的场景 安装Lua 1.安装解释器:yu ...
- 大体了解Lua的语法
Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 在Lua中,一切都是变量,除了关键字.请记住这句话. I. 首先是注释 写一个程序,总是少不了注释的. 在Lua中,你可以使用单行注释和多 ...
- Lua基础 函数(一)
转自: http://blog.csdn.net/wzzfeitian/article/details/8653101 在Lua中,函数是对语句和表达式进行抽象的主要方法.既可以用来处理一些特殊的工作 ...
- Python学习的个人笔记(基础语法)
Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...
- python基础语法及知识点总结
本文转载于星过无痕的博客http://www.cnblogs.com/linxiangpeng/p/6403991.html 在此表达对原创作者的感激之情,多谢星过无痕的分享!谢谢! Python学习 ...
- Cocos2d-x 脚本语言Lua基本语法
Cocos2d-x 脚本语言Lua基本语法 前面一篇博客对Lua这门小巧的语言进行了简单的介绍.本篇博客来给大家略微讲一下Lua的语法.不会长篇累牍得把Lua的全部语法都讲一遍,这里通过下面几点来讲L ...
随机推荐
- 【解决】Node JS Error: ENOENT
The Node Beginner Book 书中的实例代码当上传图片时会报Error: ENOENT, 原因:图片默认会选择系统的缓存文件夹下,在windows下无权访问C盘,所以就报错了.. 解决 ...
- Linux nohup 后台运行命令
有一些爬虫的程序需要在后台运行,所以简单总结了一下nohup 的一些用法 基本命令:nohup command $; 运行之后出现nohup: ignoring input and appendin ...
- 关于C标准
关于C标准 1. 前言 本文从英文 C-FAQ (2004 年 7 月 3 日修订版) 翻译而来.本文的 中文版权为朱群英和孙云所有. 本文的内容可以自由用于个人目的,但 是不可以未经许可出版发行. ...
- maven中如何得到父工程的位置
目前的项目是一个父子工程项目,想要在子工程的pom文件中操作父工程目录下的资源. maven官方提供了标准的写法,比如parent.basedir之类的,网上可以找到很多,但尝试了之后就是不识别. 搞 ...
- float与定位的区别
float和绝对定位的区别 CSS中脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位.1 需要注意的是,使用float脱离文档流时,其他盒子 ...
- [POI2011]Lightning Conductor
题面在这里 description 已知一个长度为\(n\)的序列\(a_1,a_2,...,a_n\). 对于每个\(1\le i\le n\),找到最小的非负整数\(p\), 满足对于任意的\(1 ...
- 【luogu 1439 最长公共子序列】
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...
- JS获取当前时间及时间戳相互转换
1.获取当前时间的 时间戳 Date.parse(new Date()) 结果:1486347562000 2.获取当前 时间 new Date() 结果:Mon Feb 06 2017 10:19: ...
- git使用笔记(九)操作原理
By francis_hao Nov 27,2016 参考[1]的一张图已经把git的基本原理描述的很清楚了,如下: 下面以实例演示其过程,需要用到两个命令cat-file和ls-fil ...
- [poj 3252]数位dp前导0的处理
通过这个题对于数位dp中前导0的处理有了新的认识. 题目链接:http://poj.org/problem?id=3252 //http://poj.org/problem?id=3252 #incl ...