手机如何翻到国外网站,北京外包公司名单,温州做外贸网站设计,建e全景效果图文章目录 1、Linux安装Lua2、语法练习2.1、变量2.2、循环2.3、函数2.4、数组2.5、迭代器2.6、Table操作2.7、Lua 模块与包2.8、加载机制2.9、Lua 元表(Metatable) 3、Lua 协同程序(coroutine)4、文件IO操作4.1、简单模式4.2、完全模式 5、错误处理 内容来源菜鸟教程#xff0c… 文章目录 1、Linux安装Lua2、语法练习2.1、变量2.2、循环2.3、函数2.4、数组2.5、迭代器2.6、Table操作2.7、Lua 模块与包2.8、加载机制2.9、Lua 元表(Metatable) 3、Lua 协同程序(coroutine)4、文件IO操作4.1、简单模式4.2、完全模式 5、错误处理 内容来源菜鸟教程主要列举一些重要部分和c语言有歧义的部分 https://www.runoob.com/lua/lua-file-io.html 1、Linux安装Lua
1、下载
wget http://www.lua.org/ftp/lua-5.3.0.tar.gz2、解压
tar zxf lua-5.3.0.tar.gz3、进入目录
cd lua-5.3.04、编译
make linux test5、拷贝到系统位置
make install2、测试使用 vi test.lua print(“hello world”) 保存内容
运行lua脚本 lua test.lua
3、首行加入直接可以运行 #!/usr/local/bin/lua
2、语法练习
1、… 拼接字符串可以利用nil来删除表中的值
tal {ke1 val1,ke2 val2,val3}
for k,v in pairs(tal) doprint(k .. - .. v)
endtal.ke1 nilfor k,v in pairs(tal) doprint(k,v)
end2、lua中数字字符串会默认转换成数字进行操作符运算
tal {}tal[key] val
key 10
tal[key] 10
tal[key] tal[key] 22
for k,y in pairs(tal) doprint(k,y)
end3、 lua中表中数组下标是从1开始
-- lua中表中数组下标是从1开始
tal {key1,key2,key3}
for key,val in pairs(tal) doprint(key,key)
end4、在 Lua 中函数是被看作是第一类值First-Class Value函数可以存在变量里
function fun(n)if n 0 thenreturn 1elsereturn n*fun(n-1)end
end
print(fun(5))
fun2 fun
print(fun2(5))5、function 可以以匿名函数anonymous function的方式通过参数传递:
function fun2(tal,fun)for key,val in pairs(tal) doprint(fun(key,val))end
endtal {key1 val1,key2 val2,key3 val3}
fun2(tal,
function(key,val)return key....val
end
)2.1、变量
1、Lua 变量有三种类型全局变量、局部变量、表中的域。
a 5 -- 全局变量
local b 5 -- 局部变量function joke()c 5 -- 全局变量local d 6 -- 局部变量
endjoke()
print(c,d) -- 5 nildo local a 6 -- 局部变量b 6 -- 对局部变量重新赋值print(a,b); -- 6 6
endprint(a,b) -- 5 62、赋值语句
a,b hello,111
print(a,b)-- 可以利用这种方式对变量进行交换操作
a,b 111,222
print(a,b)a,b b,a
print(a,b)3、当变量个数和值的个数不一致时Lua会一直以变量个数为基础采取以下策略 a. 变量个数 值的个数 按变量个数补足nil b. 变量个数 值的个数 多余的值会被忽略
a, b, c 0, 1
print(a,b,c) -- 0 1 nila, b a1, b1, b2 -- value of b2 is ignored
print(a,b) -- 1 2a, b, c 0
print(a,b,c) -- 0 nil nil2.2、循环 这里只是列举出与c语言不一样的地方 重复执行循环直到 指定的条件为真时为止
--[ 变量定义 --]
a 10
--[ 执行循环 --]
repeatprint(a的值为:, a)a a 1
until( a 15 )Lua 语言中的 goto 语句允许将控制流程无条件地转到被标记的语句处。
local i 0
::s1:: doprint(i)i i1
endif i 1 thengoto s1
end2.3、函数
可变参数
function add(...)local s 0 for i, v in ipairs{...} do -- {...} 表示一个由所有变长参数构成的数组 s s vendreturn s
end
print(add(1,2,3,4,5))Lua 中我们可以将函数作为参数传递给函数
myprint function (param)print(##,param,##)
endfunction add(x,y,myp)myp(xy)
endadd(10,20,myprint)将可变参数赋值给一个变量 我们也可以通过 select(“#”,…) 来获取可变参数的数量
function average(...)local arg {...} -- arg为一个表可变参local result 0for key,val in ipairs(arg) doresult result valendprint(总长度为,#arg)return result/#arg
endprint(average(1,2,3,4,56))2.4、数组
多维数组 多维数组即数组中包含数组或一维数组的索引键对应一个数组。 以下是一个三行三列的阵列多维数组
-- 初始化数组
array {}
for i1,3 doarray[i] {}for j1,3 doarray[i][j] i*jend
end-- 访问数组
for i1,3 dofor j1,3 doprint(array[i][j])end
end不同索引键的三行三列阵列多维数组
-- 初始化数组
array {}
maxRows 3
maxColumns 3
for row1,maxRows dofor col1,maxColumns doarray[row*maxColumns col] row*colend
end-- 访问数组
for row1,maxRows dofor col1,maxColumns doprint(array[row*maxColumns col])end
end2.5、迭代器
多状态的迭代器
local tab {c,c}function element(collection)local index 0local count #collection-- 闭包函数return function ()index index 1if(indexcount) thenreturn collection[index]endend
endfor e in element(tab) doprint(e)
end2.6、Table操作
Table 连接
fruits {banana,orange,apple}
-- 返回 table 连接后的字符串
print(连接后的字符串 ,table.concat(fruits))-- 指定连接字符
print(连接后的字符串 ,table.concat(fruits,, ))-- 指定索引来连接 table
print(连接后的字符串 ,table.concat(fruits,, , 2,3))连接后的字符串 bananaorangeapple 连接后的字符串 banana, orange, apple 连接后的字符串 orange, apple
插入和移除
fruits {banana,orange,apple}-- 在末尾插入
table.insert(fruits,mango)
print(索引为 4 的元素为 ,fruits[4])-- 在索引为 2 的键处插入
table.insert(fruits,2,grapes)
print(索引为 2 的元素为 ,fruits[2])print(最后一个元素为 ,fruits[5])
table.remove(fruits)
print(移除后最后一个元素为 ,fruits[5])索引为 4 的元素为 mango 索引为 2 的元素为 grapes 最后一个元素为 mango 移除后最后一个元素为 nil
Table 排序
fruits {banana,orange,apple,grapes}
print(排序前)
for k,v in ipairs(fruits) doprint(k,v)
endtable.sort(fruits)
print(排序后)
for k,v in ipairs(fruits) doprint(k,v)
end排序前 1 banana 2 orange 3 apple 4 grapes 排序后 1 apple 2 banana 3 grapes 4 orange
2.7、Lua 模块与包 模块类似一个封装库从5.1开始lua中加入了标准的模块管理机制可以将一个公共的代码放入到一个文件中以API的形式提供lua使用变量函数组成的table表创建一个模块很简单就是创建一个table表将需要导入的数据放入到table表中然后将其返回 module {}module.constant 这是一个常量-- 定义一个函数function module.func1()io.write(这是一个函数)
endlocal function func2()print(这是一个私有函数)
endfunction module.func3()func2()
endreturn module使用模块 require 函数 Lua提供了一个名为require的函数用来加载模块。要加载一个模块只需要简单地调用就可以了。例如 require(“模块名”)或者require “模块名”
-- 调用模块
-- 执行 require 后会返回一个由模块常量或函数组成的 table并且还会定义一个包含该 table 的全局变量。
require(module)print(module.constant)
module.func3()或者给加载的模块定义一个别名变量方便调用
-- test_module2.lua 文件
-- module 模块为上文提到到 module.lua
-- 别名变量 m
local m require(module)print(m.constant)m.func3()2.8、加载机制 对于自定义的模块模块文件不是放在哪个文件目录都行函数 require 有它自己的文件路径加载策略它会尝试从 Lua 文件或 C 程序库中加载模块。 require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中当 Lua 启动后会以环境变量 LUA_PATH 的值来初始这个环境变量。如果没有找到该环境变量则使用一个编译时定义的默认路径来初始化。 当然如果没有 LUA_PATH 这个环境变量也可以自定义设置在当前用户根目录下打开 .profile 文件没有则创建打开 .bashrc 文件也可以例如把 “~/lua/” 路径加入 LUA_PATH 环境变量里 #LUA_PATH
export LUA_PATH~/lua/?.lua;;文件路径以 “;” 号分隔最后的 2 个 “;;” 表示新加的路径后面加上原来的默认路径。
接着更新环境变量参数使之立即生效。
source ~/.profile这时假设 package.path 的值是
/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua那么调用 require(“module”) 时就会尝试打开以下文件目录去搜索目标。
/Users/dengjoe/lua/module.lua;
./module.lua
/usr/local/share/lua/5.1/module.lua
/usr/local/share/lua/5.1/module/init.lua
/usr/local/lib/lua/5.1/module.lua
/usr/local/lib/lua/5.1/module/init.lua如果找过目标文件则会调用 package.loadfile 来加载模块。否则就会去找 C 程序库。
搜索的文件路径是从全局变量 package.cpath 获取而这个变量则是通过环境变量 LUA_CPATH 来初始。
搜索的策略跟上面的一样只不过现在换成搜索的是 so 或 dll 类型的文件。如果找得到那么 require 就会通过 package.loadlib 来加载它。
2.9、Lua 元表(Metatable)
3、Lua 协同程序(coroutine) 协同程序与线程非常类似拥有独立的堆栈和独立的局部变量独立的指令和指针又共享全局变量协同程序可以理解为一种特殊的线程可以暂停和恢复其执行从而允许非抢占式的多任务处理。 同程序由 coroutine 模块提供支持。 使用协同程序你可以在函数中使用 coroutine.create 创建一个新的协同程序对象并使用 coroutine.resume 启动它的执行。协同程序可以通过调用 coroutine.yield 来主动暂停自己的执行并将控制权交还给调用者。
function foo()print(协同程序foo开始执行)local value coroutine.yield(让出foo的执行)print(协同程序 foo 恢复执行传入的值为: .. tostring(value))print(协同程序 foo 结束执行)return 1
end-- 创建协同程序
local co coroutine.create(foo)-- 启动协同程序
local status,result coroutine.resume(co)
print(result)-- 恢复协同程序的执行并传入一个值
status, result coroutine.resume(co, 42)
print(result) -- 输出: 协同程序 foo 恢复执行传入的值为: 42以上实例中我们定义了一个名为 foo 的函数作为协同程序。在函数中我们使用 coroutine.yield 暂停了协同程序的执行并返回了一个值 。在主程序中我们使用 coroutine.create 创建了一个协同程序对象并使用 coroutine.resume 启动了它的执行。 在第一次调用 coroutine.resume 后协同程序执行到 coroutine.yield 处暂停并将值返回给主程序。然后我们再次调用 coroutine.resume并传入一个值作为协同程序恢复执行时的参数。执行以上代码输出结果为 同程序的状态可以通过 coroutine.status 函数获取通过检查状态可以确定协同程序的执行情况如运行中、已挂起、已结束等。
-- 创建了一个新的协同程序对象 co其中协同程序函数打印传入的参数 i
co coroutine.create(function(i)print(i);end
)
-- 使用 coroutine.resume 启动协同程序 co 的执行并传入参数 1。协同程序开始执行打印输出为 1
coroutine.resume(co, 1) -- 1-- 通过 coroutine.status 检查协同程序 co 的状态输出为 dead表示协同程序已经执行完毕
print(coroutine.status(co)) -- dead
print(----------)-- 使用 coroutine.wrap 创建了一个协同程序包装器将协同程序函数转换为一个可直接调用的函数对象
co coroutine.wrap(function(i)print(i);end
)co(1)print(----------)
-- 创建了另一个协同程序对象 co2其中的协同程序函数通过循环打印数字 1 到 10在循环到 3 的时候输出当前协同程序的状态和正在运行的线程
co2 coroutine.create(function()for i1,10 doprint(i)if i 3 thenprint(coroutine.status(co2)) --runningprint(coroutine.running()) --thread:XXXXXXendcoroutine.yield()endend
)-- 连续调用 coroutine.resume 启动协同程序 co2 的执行
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --3-- 通过 coroutine.status 检查协同程序 co2 的状态输出为 suspended表示协同程序暂停执行
print(coroutine.status(co2)) -- suspended
print(coroutine.running())
print(----------)更详细的实例
function foo (a)print(foo 函数输出, a)return coroutine.yield(2 * a) -- 返回 2*a 的值
endco coroutine.create(function (a , b)
print(第一次协同程序执行输出, a, b) -- co-body 1 10
local r foo(a 1)
print(第二次协同程序执行输出, r)
local r, s coroutine.yield(a b, a - b) -- ab的值为第一次调用协同程序时传入
print(第三次协同程序执行输出, r, s)
return b, 结束协同程序 -- b的值为第二次调用协同程序时传入
end)print(main, coroutine.resume(co, 1, 10)) -- true, 4
print(--分割线----)
print(main, coroutine.resume(co, r)) -- true 11 -9
print(---分割线---)
print(main, coroutine.resume(co, x, y)) -- true 10 end
print(---分割线---)
print(main, coroutine.resume(co, x, y)) -- cannot resume dead coroutine
print(---分割线---)生产者消费者模型
-- 生产者消费者模型
-- 1、创建携程
-- 2、调用receive函数激活协程
-- 2、协程生成一个数据然后让出协程将这个数据抛出去
-- 3、receive激活携程这里收到抛出的数据然后打印出来local newProductorfunction productor()local i 0while true doi i 1send(i) -- 将生产的物品发送给消费者end
endfunction consumer()while true dolocal i receive() -- 从生产者那里得到物品print(i)end
endfunction receive()local status, value coroutine.resume(newProductor)return value
endfunction send(x)coroutine.yield(x) -- x表示需要发送的值值返回以后就挂起该协同程序
end-- 启动程序
newProductor coroutine.create(productor)
consumer()线程和协同程序区别 1、线程与协同程序的主要区别在于一个具有多个线程的程序可以同时运行几个线程而协同程序却需要彼此协作的运行。 2、在任一指定时刻只有一个协同程序在运行并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。 4、文件IO操作
4.1、简单模式 简单模式使用标准的 I/O 或使用一个当前输入文件和一个当前输出文件。 -- 以只读方式打开文件
file io.open(test.lua, r)-- 设置默认输入文件为 test.lua
io.input(file)-- 输出文件第一行
print(io.read())-- 关闭打开的文件
io.close(file)-- 以附加的方式打开只写文件
file io.open(test.lua, a)-- 设置默认输出文件为 test.lua
io.output(file)-- 在文件最后一行添加 Lua 注释
io.write(-- test.lua 文件末尾注释)-- 关闭打开的文件
io.close(file)4.2、完全模式
通常我们需要在同一时间处理多个文件。我们需要使用 file:function_name 来代替 io.function_name 方法。以下实例演示了如何同时处理同一个文件
-- 以只读方式打开文件
file io.open(test.lua, r)-- 输出文件第一行
print(file:read())-- 关闭打开的文件
file:close()-- 以附加的方式打开只写文件
file io.open(test.lua, a)-- 在文件最后一行添加 Lua 注释
file:write(--test)-- 关闭打开的文件
file:close()5、错误处理
我们可以使用两个函数assert 和 error 来处理错误。实例如下
local function add(a,b)assert(type(a) number, a 不是一个数字)assert(type(b) number, b 不是一个数字)return ab
end
add(10)error函数
error (message [, level])功能终止正在执行的函数并返回message的内容作为错误信息(error函数永远都不会返回)
通常情况下error会附加一些错误位置的信息到message头部。Level参数指示获得错误的位置:
Level1[默认]为调用error位置(文件行号)
Level2指出哪个调用error的函数的函数
Level0:不添加错误位置信息