编程语言Lua快速入门
工作需要用到Lua做一些脚本, 所以学习一下这个在游戏开发应用广泛的语言, 当然, 我更喜欢称之为撸啊撸语言…
NetSmell 出品
工作需要用到Lua做一些脚本, 所以学习一下这个在游戏开发应用广泛的语言, 当然, 我更喜欢称之为撸啊撸语言…
简介
Lua
是一种轻量语言,它的官方版本只包括一个精简的核心和最基本的库,- 性能方面, Lua比Python快(这也是脚本语言选型中不用python的原因)
- Lua与C/C++交互方便, 易于扩展
Lua
是一个动态弱类型语言, 支持增量式垃圾收集策略, 支持协程
- 支持REPL(Read-Eval-Print Loop, 交互式解释器)
-- 命令行中输入lua, 使用REPL andrew_liu:Lua/ $ lua Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio > print "hello world"-- 国际编程学习惯例 hello world > print("hello world") hello world >
安装
已经懒得再安利 brew
了(不好用你干我), 一行命令完成安装
# 安装路径为/usr/local/Cellar/lua $ brew install lua
基础语法
注释
单行注释使用 --
, 多行注释使用 --[[
和 --]]
-- 这种为单行注释 -- Date: 16/8/27 -- Time: 22:33 --[[ 这里是多行注释 --]]
变量定义
- lua中的所有变量默认为全局变量, 定义局部变量需要使用
local关键字
(是不是很变态) - 所有的数字 都是双精度浮点型(double)
- 字符串可以使用单引号和双引号, 类似于
python
中的字符串表示形式 - 使用一个
未定义的变量
不会报错, 而是返回nil(类似于C/C++中的NULL) - 一行语句可以同时定义多个变量
-- variable age = 0-- 全局变量 sum = 2-- 所有数字都是double型 str = '蛤丝'-- 字符串可以是单引号和双引号 str1 = "还是蛤丝" -- 使用`[[]]`定义多行字符串时, 其空格都会被保留 str2 = [[多行的字符串 以两个方括号 开始和结尾。]] sum = nil-- 撤销sum的定义 test = not_define print(test) name, age, sex = "andrew",18,"male","蛤丝"-- 最后一个变量会被丢弃, 而不会报错(闷死发大财才是最吼得)
if-else
if-else与python有些像, 不过需要注意if和elseif最后的 then
和末尾的 end
-- if-else age = 100 ifage <=40andage >=20then print("young man!") elseifage >40andage <100then print("old man") elseifage <20then print("too young") else print("monster") end
循环
Lua
同样支持三种循环, while循环, for循环, until循环(可以理解为C/C++中的do-while循环)
while循环
当条件满足, 会一直执行循环体
-- while
num=0
whilenum<10do
print(num)
num=num+1
end
for循环
-- for
sum=0
-- 1表示从1开始, 10表示最大为10(包含10)
-- C++: for (int i = 1, i <= 10, ++i)
fori =1,100do-- 包含1和100
sum=sum+ i
end
-- 类似于Python中的range操作, 2表示, 每次循环后i执行+2操作
-- C++: for (int i = 1, i <= 10, i = i + 2)
fori =1,10,2do-- 1,3,5,7,9
print(i)
sum=sum+ i
end
-- ..操作符用于连接字符串, 可以理解为python中字符串的+
操作
print("sum = "..sum)
until循环, 类似于C/C++中的do-while语句
-- until(do-while) sum=2 -- 中文: 直到sum的值大于1000时, 才终止循环 repeat sum=sum^2-- 幂操作 untilsum>1000 print("do-while, sum = "..sum)
函数
- 函数在Lua中是一等公民
- 支持有名和匿名函数
- 函数最后有个end, 写C/C++/Python的可能不太适应
- 函数支持一次`返回多个变量
- 局部函数的定义只需要在函数前加个
local
, 和局部变量类似
-- function(return支持返回多个值), 函数是一等公民 functionadd(a,b) returna+ b end print("1 + 2 = "..add(1,2)) -- 匿名函数 f = function(a,b) returna* b end print ("匿名函数: ".. f(2,3))
递归(经典: 斐波那契)
functionfib(n)
ifn <2thenreturnnend
returnfib(n -2) + fib(n -1)
end
Table
Table
是Lua中核心数据结构, 我理解为其他语言中的 Dict/Map
数据结构(key-value的数据结构), 而数组等在Lua中都是通过 Table
来表示的
Table可以使用任何非nil的值作为key
--Lua唯一的组合数据结构 -- 可以使用任何非nil值作为key --Table(key-value数据结构) map = { name = "andrew", -- 此处name默认使用字符串作为key age = 18, sex = "male" } -- 上下两种写法等价 --map = {['name'] ='andrew', ['age'] =18, ['sex'] ='male'}
对Table创建, 读取, 更新和删除操作, key-value的读取可以通过 .
符号
-- Table的CRUD map['hobby'] ="膜蛤"--map.hobby ="膜蛤" print(map.name) map.age =19 map.sex =nil -- 删除key
遍历一个Table
-- 遍历一个Table fork, vinpairs(map)do print(k, v) end
数组/列表
- 数组是通过Table来实现的
Lua
中数组的下标是从1开始, 从1开始, 从1开始. 重要的事情说三遍.
-- array, 数组下标从1开始 -- 数组中可以是不同类型的数据 arr = {"string",100,"andrew",function()print("hello world")end} -- 等价于 -- arr = {[1]="string", [2]=100, [3]="andrew", [4]=40, [5]=function()print("hello world")end} fori =1,#arr do -- #arr表示数组的长度 print(arr[i]) end
元表(metatable)
Table的 metatable
提供一种类似于操作符重载的机制, 写个python的可能重写个 __add__
方法, 感觉有点类似
- 通过
setmetatable
将自己实现的metamethod绑定到对应的Table对象中
-- table的元表提供一种机制,支持操作符重载 data_one = {a=1, b =2}-- data_one和data_two 可以看做表示1/2和3/4 data_two = {a=3, b =4} meta_fraction = {} -- 新定义一个元表 functionmeta_fraction.__add(f1,f2) --__add是build-in的原方法 localsum= {} sum.b = f1.b * f2.b sum.a= f1.a* f2.b + f2.a* f1.b returnsum end setmetatable(data_one, meta_fraction) -- 为之前定义的两个table设置metatable setmetatable(data_two, meta_fraction) s = data_one + data_two -- 执行 + 操作
- 元表的
__index
可以重载用于查找的点操作符, 我理解有点类似于python中的__getattr__
, 对类中的属性做查找
-- 当表要索引一个值时如table[key], Lua会首先在table本身中查找key的值, -- 如果没有并且这个table存在一个带有__index属性的Metatable, 则Lua会按照__index所定义的函数逻辑查找 default_map = {name = 'andrew', sex ='male'} new_map = {age = 18} setmetatable(default_map, {__index = new_map}) print(default_map.name, default_map.age)-- 继承了new_map的属性
元方法(metamethod)
__add
这种方法在Lua中被称为元方法,
-- __add(a, b)fora + b -- __sub(a, b)fora - b -- __mul(a, b)fora * b -- __div(a, b)fora / b -- __mod(a, b)fora % b -- __pow(a, b)fora ^ b -- __unm(a)for-a -- __concat(a, b)fora .. b -- __len(a)for#a -- __eq(a, b)fora == b -- __lt(a, b)fora < b -- __le(a, b)fora <= b -- __index(a, b) <fn or a table>for a.b -- __newindex(a, b, c)fora.b = c -- __call(a, ...)fora(...)
继承
继承
同样是通过元表和元方法来实现的.
-- table实现继承 Dog = {} -- 这个new函数我理解为继承类的构造函数, 冒号(:)函数会使参数默认增加一个self作为参数 functionDog:new() -- 下面这句相当于继承的类增加的新的成员变量 localnew_obj = {sound ='woof'} self.__index = self returnsetmetatable(new_obj, self) end functionDog:make_sound()-- 等价于Dog.make_sound(Dog) print("say ".. self.sound) end -- 使用 new_dog = Dog:new() -- new_dog获得Dog的方法和变量列表 new_dog:make_sound()
self.__index = self
是防止self被扩展后改写,所以,让其保持原样setmetatable(new_obj, self)
会返回第一个参数, new_obj会得到self的函数Dog:new()
调用方式会增加一个隐式参数self
模块
- require函数, 第一次执行后有缓存, 所以载入同样的lua文件时, 只有第一次的时候会去执行, 多次执行同一句require, 只有第一次生效
- dofile函数, 类似于require, 但无缓存, 每次语句都会重新执行一次
- loadfile加载一个lua文件, 但是并不运行它, 只要在需要的时候再像函数一样执行它
--module --1.require local test = require('module') -- require文件会被缓存 -- test.say_my_name() -- 不能调用local test.say_hello() --2. dofile 类似require但不缓存 --3. loadfile加载一个lua文件, 但是并不运行它
参考链接
显示余下内容
相关文章:
国漫【斗罗大陆】小舞 粉色 连衣裙 美女手机壁纸
「可怜的东西」尺度炸裂,女神这么脱,值么?
《蜘蛛夫人》别看,史上最差超英电影,烂到家了!
《凯洛的末日日常》Netflix新片末日疯狂跌破眼镜!
《利益区域》不见血的暴行!尺度堪比禁片,不寒而栗
《忍者神威》开局9.1分!好久没这么爽了
《爱爱内含光》这部性喜剧,除了性还能看到什么?
「杀人者的难堪」他这一锤,拿下网飞Top1
《群星》Apple TV开年惊悚王炸!美剧又出息了!
「阿盖尔:神秘特工」太意外了,年后第一部大片,竟然这么爽!
奥斯卡最大黑马?全片无台词的电影凭什么!
剧版《史密斯夫妇》瞎改经典,全网抵制,打脸了?
2024必看神作!《首尔之春》太敢拍了!
韩剧《共助》从头爽到尾,这部谍战电影帅爆了!
地狱客栈 第一季 8.6,该动画已屏蔽全体儿童
《杀人者的购物中心》又来一部王炸爽剧,杀疯了
《12年级的失败》神片来袭,印度版“小镇做题家”太上头!
《地狱客栈》第一季单集9.0分,千年等一回,这神仙动画我爱了
《荒野》马东锡血浆片,虽烂但爽
韩剧《观相》豪华阵容 狂飙演技,宋康昊首部古装大片!
电影「花千骨」怒冲3.5,「开年第一烂」出现了!
发表回复