《Lua程序设计 第二版》学习笔记一

Lua简介

Lua是一种简单、可拓展、可移植及高效的脚本语言。

开始

  1. Lua之间不需要分隔符

  2. 运行方式:
    Linux下:

lua -i prog
dofile("lib1.lua")
  1. 函数定义:
function func()
	return 123;
end
  1. 词法规范
    标识符可以以任意字母、数字、下划线构成,但是不能以数字开头,避免下划线后面跟一个或多个大写字母,这类字符被Lua保留作为特殊用途。保留字有:andbreakdoelseelseifendfalseforfunctionifinlocalnilnotorrepeatreturnthentrueuntilwhile

  2. 全局变量
    全局变量不需要声明,删除直接赋值为nil

  3. 本地变量
    使用local声明

数据类型

  1. nil
  2. boolean
  3. number
  4. string
  5. table
  6. function
  7. userdata(自定义类型)
  8. thread(线程)

表达式

  1. 算数操作符:+ - * / ^(指数) -(负号)
  2. 关系操作符:< > <= >= == ~=
  3. 逻辑操作符:and or not,其中nil值视为false
  4. 字符串连接:..
  5. 优先级:直接使用括号分离
  6. table构造式 names = {"jack", "bill", "green"}

语句

  1. 赋值
a = "hello" .. "world"
t.n = t.n + 1
a, b = 10, 2 * x
x, y = y, x 交换
  1. 局部变量与块(block)
j = 10
local i - 1

使用关键字do-end可以控制局部变量作用域

do
local a = 10
...
end
  1. 控制结构
    if then else
if a < 0 then a = 0 end
if a < b then return a else return b end
if line	> MAXLINES then
	showpage()
	line = 0
end
if op == "+" then 
	r = a + b
elseif op == "-"
	r = a -b
elseif op == "*"
	r = a * b
else 
	error("Invalid operation")
end

while

local i = 1
while a[i] do
	print(a[i])
	i = i + 1
end

repeat

repeat
	line = io.read()
until line ~= ""
print(line)

数字型for

for (var = exp1, exp2, exp3) do
	<执行体>
end
var从exp1变化到exp2,每次以exp3作为步长递增var,并执行一次执行体、exp3是可选的,默认为1
for i = 1, 10 do print(i) end
for i = 10, 1, -1 do print (i) end

泛型for

for i, v in ipairs(a) do print(v) end

ipairs遍历数组的迭代器函数,每次循环中,i会被赋予一个索引值,v被赋予一个对应于该索引的数组元素值。

for k in pairs(t) do print(k) end
  1. break 和 return
...

函数

  1. 多重返回值
function maxinum (a)
	local mi = 1;
	local m = a[mi]
	for i, val in ipairs(a) do
		if val > m then
			mi = i; m = val
		end
	end
		return m, mi
end
print(maxinum({8, 10, 23, 12, 5}))	--> 23 3

若将函数调用作为一条单独语句时,Lua会丢弃函数的所有返回值。若将函数作为表达式的一部分来调用时,Lua只保留函数的第一个返回值。只有当一个函数调用是一系列表达式中的最后一个元素时,才能获得它的所有返回值。
unpack:接受数组为参数,并从下标1开始返回数组的所有元素。

print(unpack({10,20,21}))
a, b = unpack{10,20,21}
  1. 变长参数
function add(...)
	local s = 0
		for i, v in ipairs{...} do
			s = s + v
		end
	return s 
end
print(1,2,3,4)
function foo (...)
	local a, b, c = ...
end
select("i", ...) 获取第i个变参参数
select("#", ...) 获取所有变参参数的总数
  1. 具名实参
rename{old="temp.lua", new="temp1.lua"}
function rename (arg)
	return os.rename(arg.old, arg.new)
end

深入函数

闭包closure

非局部变量 non-local variable

function newCounter()
	local i = 0
return function () 
	i = i + 1
	return i
	end
end
 
c1 = newCounter();
print(c1())
print(c1())
c2 = newCounter();
print(c2())
print(c1())
print(c2())

非全局的函数

正确的尾调用
retun ()

迭代器与泛型

迭代器
迭代器的闭包实现:

function values(t)
	local i = 0
	return function()
		i = i + 1
		return t[i]
	end
end
 
local vals = {1,100,32,123,42}
 
local iter = values(vals);
普通调用
print(iter())
print(iter())
遍历
for element in values(vals) do
	print(element)
end

泛型for

for <var-list> in <exp-list> do
	<body>
end

协同程序

协程拥有自己独立的栈、局部变量和指令指针,同时又与其他协同程序共享全局变量和其他大部分东西。从概念上线程和协程的主要区别在于:一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此写作的运行。就是说,一个具有多个协同程序的程序在任意时刻只能运行一个协程程序,并且正在运行的协同程序只会在其显示地要求挂起时,它的执行才会暂停。

co = coroutine.create(function() print("hi") end) 
 
print(co)
 
print(coroutine.status(co))

coroutine.resume(co)

print(coroutine.status(co))

原文地址:https://www.cnblogs.com/liushijie/p/4930066.html