赞
踩
Lua是由Roberto Ierusalimschy、Luiz Henrique de Figueiredo和Waldemar Celes于1993年创建的,当时他们是巴西里约热内卢天主教大学计算机图形技术组(Tecgraf)的成员。在开发Lua之前,他们曾参与过数据描述/配置语言"SOL"(简单对象语言)和"DEL"(数据录入语言)的工作。这两种语言是他们独立开发的两个不同项目的一部分,旨在增强工程应用的交互式图形程序。然而,SOL和DEL缺乏许多控制流结构,因此需要增加完整的编程能力。因此,为了满足这个需求,他们创建了Lua。
在《The Evolution of Lua》中,Lua的作者写道,在1993年,Tcl是Lua的唯一真正竞争者,但Tcl的语法相对较为陌生,且只能在Unix平台上运行,不太适合数据描述。此外,LISP和Scheme的语法也不够友好,Python还处于起步阶段。在Tecgraf的自由、自主的氛围下,他们自然而然地尝试开发自己的脚本语言。考虑到这门语言的潜在用户不一定是专业程序员,因此他们希望语言避免复杂的语法和语义。另外,由于Tecgraf的客户使用各种不同的计算机平台,他们希望新语言的实现能够高度可移植。最后,考虑到Tecgraf的其他产品也需要嵌入脚本语言,他们决定让新语言像SOL一样提供带有C API的库。
Lua 作为一种脚本语言具有多种特点,以下是其中一些主要的特点:
end
关键字来结束块,使得代码更加清晰易读。load
和 loadfile
函数动态加载并执行 Lua 脚本,灵活性很高。脚本语言是一种用于编写脚本的编程语言。
脚本是一系列按照特定顺序执行的命令或指令,通常用于自动化任务、配置文件、批处理处理、快速原型开发等场景。脚本语言通常被设计为易于编写和理解,其语法和结构往往更加简单直观。
脚本语言与编译型语言的主要区别在于,脚本语言不需要经过编译成机器代码的过程,而是由解释器逐行解释执行。这使得脚本语言的开发和调试更加快速和灵活,因为开发者可以立即看到代码的效果,而不需要额外的编译步骤。
脚本语言通常用于各种不同的领域,包括:
总的来说,脚本语言是一种简单、灵活且功能强大的编程语言,适用于各种不同的应用场景,能够大大提高开发效率和灵活性。
解释性语言和编译性语言是两种不同类型的编程语言
解释性语言:
编译性语言:
https://www.lua.org/download.html
lua-5.4.6.tar.gz
tar -xzf lua-5.4.6.tar.gz
lua-5.4.6
cd lua-5.4.6 //进入目录
make //编译
sudo make install //安装
lua -v
Lua 5.4.6
https://wiki.luatos.com/
Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。
Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用:
$ lua
$ Lua 5.4.6 Copyright (C) 1994-2023 Lua.org, PUC-Rio
>
在命令行中,输入以下命令:
> print("Hello World!")
接着我们按下回车键,输出结果如下:
> print("Hello World!")
Hello World!
>
我们可以将 Lua 程序代码保存到一个以 lua 结尾的文件,并执行,该模式称为脚本式编程,如我们将如下代码存储在名为 hello.lua 的脚本文件中:
vim hello.lua
print("Hello world!")
终端运行
$ lua hello.lua
hello world!
两个减号是单行注释:
--
--[[
多行注释
多行注释
]]--
在 Lua 中,标识符是用于命名变量、函数、以及其他用户定义的东西的名称。Lua 中的标识符遵循以下规则:
_
组成。_
开始,不能以数字开头。myVariable
和 MyVariable
是两个不同的标识符。if
、then
、else
、while
、function
等)不能用作标识符。例如,以下是一些合法的 Lua 标识符:
myVar
_count
table1
变量名
而以下是一些不合法的 Lua 标识符:
3abc
(以数字开头)if
(关键字)my-variable
(包含连字符 -
)#table
(包含特殊字符 #
)注意:
最好不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的
and | break | do | else |
---|---|---|---|
elseif | end | false | for |
function | if | in | local |
nil | not | or | repeat |
return | then | true | until |
while | goto |
Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
数据类型 | 描述 |
---|---|
nil | 用于表示空或未初始化的值。 |
boolean | 只有两个值,true 和 false,用于表示逻辑值。 |
number | 用于表示数值,包括整数和浮点数。 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | 是 Lua 中最重要的数据结构,用于表示数组、字典、集合等复杂数据结构 |
Lua 是一种动态类型语言,变量的类型是根据赋给它们的值自动确定的。
a = 1;
在默认情况下,变量总是认为是全局的。
全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil。
> print(b)
nil
> b=10
> print(b)
10
如果你想删除一个全局变量,只需要将变量赋值为nil。
b = nil
print(b) --> nil
这样变量b就好像从没被使用过一样。换句话说, 当且仅当一个变量不等于nil时,这个变量即存在。
如果想使用局部变量,在变量前加 local
关键字
局部变量的作用域通常是从声明处到当前语句块结束。
local c = 10 -- 这是一个局部变量
a,b = 1,2
print(a,b)
1 2
a,b,c = 1,2
print(a,b)
1 2 nil
-- 整型
a = 1
-- 浮点型
b = 2.1
-- 科学计数法
c = 1e3
-- 十六进制
d = 0x11
print(a,b,c,d)
1 2.1 1000.0 17
-- 获取字符 'A' 的 ASCII 码值
asciiValue = string.byte('A')
-- 输出 ASCII 码值
print(asciiValue) -- 输出 65
字符串由一对双引号或单引号来表示
a = "hello"
b = 'world'
print(a,b) -- hello world
支持在字符串中插入转义字符
c = "hello\nworld"
print(c) -- hello
world
长字符串
d = [[hello
world
!]]
print(d)
获取字符串长度(#)
a = "hello world"
print(#a) --11
字符串合并(…)
a = "hello"
b = "world"
c = a..b
print(c) -- helloworld
数值字符可以和数值直接进行运算
a = "10" + 1
print(a) -- 11.0
tostring() 和 tonumber()
a = tostring(10)
print(type(a)) --string
b = tonumber("10")
print(type(b)) --number
-- 转换失败 nil
c = tonumber("abc")
print(type(c)) --nil
Lua 和 C 中的对比:
赋值运算符:
=
(单等号)=
算术运算符:
+
, -
, *
, /
, %
+
, -
, *
, /
, %
关系运算符:
==
, ~=
, <
, <=
, >
, >=
==
, !=
, <
, <=
, >
, >=
逻辑运算符:
and
, or
, not
&&
, ||
, !
位运算符:
&
, |
, ~
, <<
, >>
&
, |
, ~
, <<
, >>
连接运算符:
..
(用于连接字符串)+
(用于连接字符串)其他运算符:
#
(取长度)、:
(用于对象方法调用)sizeof
(取大小)if condition then
-- 当 condition 为 true 时执行这里的代码
else
-- 当 condition 为 false 时执行这里的代码
end
-- 定义一个变量
local temperature = 25
-- 判断温度是否超过 20 度
if temperature > 20 then
print("天气很热,建议穿短袖")
else
print("天气不算太热,可以穿长袖")
end
if condition1 then
-- 当 condition1 为 true 时执行这里的代码
elseif condition2 then
-- 当 condition1 不满足,而 condition2 为 true 时执行这里的代码
else
-- 当上述条件都不满足时执行这里的代码
end
-- 定义一个变量
local hour = 15
-- 判断当前时间段
if hour < 12 then
print("现在是上午")
elseif hour >= 12 and hour < 18 then
print("现在是下午")
else
print("现在是晚上")
end
local result = condition and value1 or value2
--如果 condition 为 true,则返回 value1,否则返回 value2
-- 定义一个变量
local score = 85
-- 使用三元运算符判断成绩是否及格
local result = score >= 60 and "及格" or "不及格"
-- 输出结果
print("成绩:" .. score .. ",考试结果:" .. result)
注意:Lua 中没有直接的 switch/case 语句。但你可以使用多个 if-elseif-else 结构来模拟类似的行为:
local choice = 2
if choice == 1 then
-- 处理选择 1 的情况
elseif choice == 2 then
-- 处理选择 2 的情况
elseif choice == 3 then
-- 处理选择 3 的情况
else
-- 处理其他情况
end
for var = startValue, endValue, stepValue do
-- 循环体
end
var
是循环变量,它从 startValue
开始递增,直到达到或超过 endValue
,每次递增 stepValue
。startValue
、endValue
和 stepValue
是可选的,默认值分别为 1、endValue
、1。var
的值会保留在循环作用域中(追踪循环结束时的变量值、利用循环变量的最终值进行后续操作、利用循环变量的最终值进行条件判断)。for i = 1, 5 do
print("数值型 for 循环,第 " .. i .. " 次迭代")
end
for index, value in ipairs(iterable) do
-- 循环体
end
iterable
是一个可迭代的对象,例如数组或表。index
和 value
分别表示当前元素的索引和值。ipairs()
函数用于迭代数组类型的表,它返回三个值:迭代函数、表、初始值。local fruits = {"apple", "banana", "orange"}
for index, fruit in ipairs(fruits) do
print("泛型 for 循环,第 " .. index .. " 个水果是 " .. fruit)
end
while condition do
-- 循环体
end
while
循环会在 condition
为 true 时执行循环体,直到 condition
为 false 才停止循环。
local j = 1
while j <= 5 do
print("while 循环,第 " .. j .. " 次迭代")
j = j + 1
end
repeat
-- 循环体
until condition
repeat until
循环会先执行一次循环体,然后检查 condition
,如果 condition
为 true,则继续执行循环体,直到 condition
为 false 才停止循环。
local k = 1
repeat
print("repeat until 循环,第 " .. k .. " 次迭代")
k = k + 1 -- lua 没有 k++ 也可以 k += 1
until k > 5
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
--函数返回两个值的最大值
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
函数调用可以通过函数名加上一对圆括号来完成,可以传入函数定义中所需的参数。
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))
在 Lua 中,函数可以返回多个值。调用函数时,可以使用逗号分隔多个返回值。
function f()
return 1, 2, 3
end
local a, b, c = f()
print(a, b, c) -- 输出: 1 2 3
匿名函数在 Lua 中是一种特殊的函数,它们不需要显式地命名,通常用于一次性的、简单的操作或作为其他函数的参数。
local double = function(x)
return x * 2
end
print(double(5)) -- 输出: 10
在 Lua 中,函数可以作为参数传递给其他函数,也可以作为其他函数的返回值。
function applyFunction(func, value)
return func(value)
end
print(applyFunction(double, 5)) -- 输出: 10
在 Lua 中,函数可以接受变长参数,可以通过 ...
表示。可以使用 select()
函数获取变长参数的值
function sum(...)
local result = 0
for i = 1, select("#", ...) do
result = result + select(i, ...)
end
return result
end
print(sum(1, 2, 3, 4, 5)) -- 输出: 15
在 Lua 中,select
是一个用于操作可变数量参数的函数。它可以用于获取可变参数的数量和值。
select
函数的一般形式为:
select(index, ...)
其中:
index
是一个索引值,用于选择可变参数列表中的参数。...
是可变参数列表。select
函数有两种主要用法:
当 index
的值为 "#"
时,select
函数返回可变参数的数量。
示例:
luaCopy codelocal count = select("#", 1, 2, 3, 4, 5)
print(count) -- 输出: 5
当 index
的值为一个整数时,select
函数返回可变参数列表中对应索引位置的参数值。
示例:
luaCopy codelocal value = select(3, "a", "b", "c", "d")
print(value) -- 输出: c
在这个示例中,select(3, "a", "b", "c", "d")
返回可变参数列表中第 3 个参数的值,即 "c"
。
需要注意的是,select
函数只能用于处理从 1 开始的索引位置,而不支持负数索引。如果 index
大于可变参数的数量,select
函数返回 nil
。
数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。在 Lua 中,数组不是一种特定的数据类型,而是一种用来存储一组值的数据结构。实际上,Lua 中并没有专门的数组类型,而是使用一种被称为 “table” 的数据结构来实现数组的功能。Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。在 Lua 索引值是以 1 为起始。
-- 创建一个数组
local myArray = {10, 20, 30, 40, 50}
-- 访问数组元素
print(myArray[1]) -- 输出 10
print(myArray[3]) -- 输出 30
print(myArray[-1]) -- 输出 50
要计算数组的长度(即数组中元素的个数),你可以使用 # 操作符:
local myArray = {10, 20, 30, 40, 50}
-- 计算数组长度
local length = #myArray
print(length) -- 输出 5
一维数组可以用 for 循环出数组中的元素
-- 创建一个数组
local myArray = {10, 20, 30, 40, 50}
-- 循环遍历数组
for i = 1, #myArray do
print(myArray[i])
end
在 Lua 中,table
是一种用来保存多个值的数据结构,它类似于其他编程语言中的数组、列表、字典或哈希表。table
是 Lua 中最重要的数据结构之一,也是 Lua 的核心之一。
数字下标的表是 Lua 中常见的数据结构,通常用来表示数组或列表。在这样的表中,键是从 1 开始的整数索引,对应的值可以是任意类型的 Lua 值。
在 Lua 的数字下标表中,每个元素可以是任何 Lua 支持的数据类型,包括但不限于:
数字(number):整数或浮点数。
字符串(string):任意长度的文本字符串。
布尔值(boolean):true 或 false。
表(table):嵌套的表,用来表示更复杂的数据结构。
函数(function):可执行的代码块。
线程(thread):Lua 的协程,用于实现轻量级并发。
用户数据(userdata):C 语言中的数据类型,通常由 Lua 扩展库创建。
这意味着你可以将任何 Lua 支持的数据类型存储在数字下标表中的元素中。例如,你可以创建一个包含字符串、数字和表的数组,或者将函数作为数组的元素,以及其他更复杂的数据组合。
local myArray = {10, "hello", true, {20, 30}, function() print("This is a function") end}
在 Lua 中,数组的索引从 1 开始,所以第一个元素的索引是 1,第二个元素的索引是 2,以此类推。
print(myArray[1]) -- 输出: 10
print(myArray[2]) -- 输出: hello
print(myArray[3]) -- 输出: true
print(myArray[4][1]) -- 输出: 20
myArray[5]() -- 输出: This is a function
如果在数字下标表中某个索引位置没有存储任何值,Lua 会返回 nil
。
print(myArray[5]) --输出: nil
以下是几种常见的往数字下标表中添加元素的方法:
可以直接通过索引赋值的方式往表中添加元素。
luaCopy codelocal myArray = {10, 20, 30}
-- 直接赋值给新的索引位置
myArray[4] = 40
可以使用 table.insert() 函数往数组末尾添加新元素。
luaCopy codelocal myArray = {10, 20, 30}
-- 使用 table.insert() 函数往数组末尾添加新元素
table.insert(myArray, 40)
table.insert (table, [pos,] value)
在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾.
luaCopy codelocal myArray = {10, 20, 30}
-- 使用 table.insert() 函数往数组第二个位置添加新元素
table.insert(myArray,2, 40)
--myArray = {10, 40,20, 30}
可以使用 # 操作符来获取数组长度,然后在长度加一的位置赋值。
luaCopy codelocal myArray = {10, 20, 30}
-- 在数组长度加一的位置赋值
myArray[#myArray + 1] = 40
table.remove()
函数table.remove()
函数用于删除数组中的元素。它接受两个参数:数组和要删除的元素的索引。删除元素后,后续的元素会向前移动填补空缺。如果不指定索引,则默认删除数组的最后一个元素。
luaCopy codelocal myArray = {10, 20, 30, 40}
table.remove(myArray) -- 删除最后一个元素
luaCopy codelocal myArray = {10, 20, 30, 40}
table.remove(myArray, 2) -- 删除索引为 2 的元素
第二个元素 20 将被删除,数组变成 {10, 30, 40}
。
table.remove()
函数在删除元素后会返回被删除的元素的值。如果指定了要删除的元素的索引,则返回该索引位置上的元素值;如果没有指定索引,则默认删除数组的最后一个元素,并返回该元素的值。
local myArray = {10, 20, 30, 40}
local removedValue = table.remove(myArray, 2) -- 删除索引为 2 的元素
print(removedValue) -- 输出: 20
local myArray = {10, 20, 30, 40}
local removedValue = table.remove(myArray) -- 删除数组的最后一个元素
print(removedValue) -- 输出: 40
nil
直接将要删除的元素的位置赋值为 nil
,这会将该位置上的元素删除,但不会改变数组的长度或索引。
luaCopy codelocal myArray = {10, 20, 30, 40}
myArray[2] = nil -- 删除索引为 2 的元素
在这个示例中,第二个元素 20 将被删除,数组变成 {10, nil, 30, 40}
。
注意:虽然元素被删除了,但数组长度仍然保持不变。
local myTable = {key1 = "value1", key2 = "value2"}
在 Lua 中,表的键(key)和值(value)可以是任何类型的 Lua 值,包括但不限于:
local myTable = {
["name"] = "John", -- 字符串作为键
[42] = "answer", -- 数字作为键
[true] = "yes", -- 布尔值作为键
[{}] = "empty table", -- 表作为键
[function() return "key" end] = "computed key", -- 函数作为键
["array"] = {1, 2, 3}, -- 数组作为值
["nestedTable"] = { -- 嵌套表作为值
["key1"] = "value1",
["key2"] = "value2"
},
["nilValue"] = nil -- nil 作为值
}
Lua 中键和值可以不带方括号。当键是字符串或者符合 Lua 变量命名规则的标识符时,可以直接使用键名来定义键值对,而无需使用方括号
local myTable = {
name = "John", -- 字符串作为键
age = 30, -- 字符串作为键
isAdult = true, -- 字符串作为键
hobbies = {"reading", "swimming"}, -- 字符串作为键, 表作为值
greet = function() print("Hello, Lua!") end, -- 字符串作为键, 函数作为值
}
要访问 Lua 表中的值,可以使用下标(键)来获取对应的值。在 Lua 中,可以使用表的键来访问表中的值,这可以通过使用方括号加上键名或者直接使用键名来完成。
local myTable = {
name = "John",
age = 30,
isAdult = true,
hobbies = {"reading", "swimming"},
greet = function() print("Hello, Lua!") end,
}
-- 使用方括号加上键名来访问表中的值
print(myTable["name"]) -- 输出: John
print(myTable["age"]) -- 输出: 30
-- 直接使用键名来访问表中的值
print(myTable.name) -- 输出: John
print(myTable.age) -- 输出: 30
直接赋值
直接通过赋值操作来向表中添加新元素,如果键不存在,则会创建新的键值对
local myTable = {} -- 创建一个空表
-- 直接赋值给新的键
myTable["name"] = "John"
myTable["age"] = 30
将要删除的元素赋值为 nil
local myTable = {name = "John", age = 30, city = "New York"}
-- 删除键为 "age" 的整个键值对
myTable["age"] = nil
pairs()
遍历表中所有的键值对
pairs()
的使用格式:
for key, value in pairs(table) do
-- 在这里处理 key 和 value
end
其中,table
是要迭代的表,key
和 value
分别是每次迭代中表中的键和对应的值。
local myTable = {name = "John", age = 30, city = "New York"}
for key, value in pairs(myTable) do
print(key, value)
end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。