lua

来源:互联网 发布:java gradle 打包命令 编辑:程序博客网 时间:2024/05/01 05:12
1: 字符串转化为数字类型, tonumber
数字类型转化为字符串, tostring
.. 为字符串连接运算符
print (0 .. 1) --> 01
print (10 .. "" == "10") 等价于 print (tostirng(10) == "10")

2:
C 语言中的三元运算符
a?b:c
在 Lua 中可以这样实现:
(a and b) or c

3: 除了^和..外所有的二元运算符都是左连接的。
x^y^z <--> x^(y^z)

4: 遇到赋值语句,lua会首先计算右边所有的值,然后赋值给左边,也就是隐式创建了临时变量,所以可以进行变量的交换

x, y = y, x -- swap x,y的值
a[i], a[j] = a[j], a[i] -- swap a[i],a[j]的值

5: 当变量个数和值的个数不一致时,Lua 会一直以变量个数为基础采取以下策略:

 a. 变量个数>值的个数 按变量个数补足nil
b. 变量个数<值的个数 多余的值会被忽略

例如:
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
a, b = a+1, b+1, b+2
print(a,b) --> 1 2
a, b, c = 0 --> 0 nil nil
print(a,b,c)

6: 第一,当作为表达式调用函数时,有以下几种情况:
1. 当调用作为表达式最后一个参数或者仅有一个参数时,根据变量个数函数尽可能
多地返回多个值,不足补 nil,超出舍去。
2. 其他情况下,函数调用仅返回第一个值(如果没有返回值为 nil)

假设有如下三个函数:
function foo0 () end -- returns no results
function foo1 () return 'a' end -- returns 1 result
function foo2 () return 'a','b' end -- returns 2 results

x,y = foo2(), 20 -- x='a', y=20
x,y = foo0(), 20, 30 -- x='nil', y=20, 30 is discarded

第二,函数调用作为函数参数被调用时,和多值赋值是相同。

print(foo0()) -->
print(foo1()) --> a
print(foo2()) --> a b
print(foo2(),1) --> a 1
print(foo2() .. "x") --> ax

第三,函数调用在表构造函数中初始化时,和多值赋值时相同。

a = {foo0()} -- a = {} (an empty table)
a = {foo1()} -- a = {'a'}
a = {foo2()} -- a = {'a', 'b'}
a = {foo0(), foo2(), 4} -- a[1] = nil, a[2] = 'a', a[3] = 4

另外,return f()这种类型的返回 f()返回的所有值

function foo (i)
if i == 0 then return foo0()
elseif i == 1 then return foo1()
elseif i == 2 then return foo2()
end
end

print(foo(1)) --> a
print(foo(2)) --> a b
print(foo(0)) -- (no results)
print(foo(3)) -- (no results)

可以使用圆括号强制使调用返回一个值。一个 return 语句如果使用圆括号将返回值括起来也将导致返回一个值。

print((foo0())) --> nil
print((foo1())) --> a
print((foo2())) --> a

7: 利用可变参数声明一个 select 函数:
function select (n, ...)
return arg[n]
end
print(string.find("hello hello", " hel")) --> 6 9
print(select(1, string.find("hello hello", " hel"))) --> 6
print(select(2, string.find("hello hello", " hel"))) --> 9

8: 闭包。

function newCounter()
local i = 0
return function() i=i+1
return i
end
end

闭包内的匿名函数使用 upvalue i 保存他的计数,当我们调用匿名函数的时候 i 已经超出了作 用范围,因为创建 i 的函数 newCounter 已经返回了。然而 Lua 用闭包的思想正确处理了这种情况。

c1 = newCounter()
print(c1) --> function: 0x8af6750
print(c1()) --> 1
print(c1()) --> 2

print(newCounter()) --> function: 0x8af6c60

print(newCounter()) --> function: 0x8af6c60

print(newCounter()()) --> 1

print(newCounter()()) --> 1

由此可见,闭包函数返回的是一个函数,当再次调用这个返回的函数的时候,他访问的外部的变量依然存在在某个作用域

简单的说闭包是一个函数加上它可以正确访问的 upvalues。如果我们再次调 用 newCounter,将创建一个新的局部变量 i,因此我们得到了一个作用在新的变量 i 上的 新闭包。

c2 = newCounter()
print(c2()) --> 1
print(c1()) --> 3
print(c2()) --> 2

9: 非全局函数
Lua 中函数可以作为全局变量也可以作为局部变量,我们已经看到一些例子:函数 作为table的域(大部分Lua标准库使用这种机制来实现的比如io.read、math.sin)。这种 情况下,必须注意函数和表语法:
1. 表和函数放在一起
Lib = {}
Lib.foo = function (x,y) return x + y end
Lib.goo = function (x,y) return x - y end

2. 使用表构造函数
Lib = {
foo = function (x,y) return x + y end,
goo = function (x,y) return x - y end
}

3. Lua 提供另一种语法方式
Lib = {}
function Lib.foo (x,y)
return x + y
end
function Lib.goo (x,y)
return x - y
end

当我们将函数保存在一个局部变量内时,我们得到一个局部函数,也就是说局部函 数像局部变量一样在一定范围内有效。
下面是声明局部函数的两种方式:
1. 方式一

local f = function (...)
...
end
local g = function (...)
...
f() --externallocal`f'isvisiblehere
...
end

2. 方式二
有一点需要注意的是在声明递归局部函数的方式:
local function f (...)
...
end

local fact = function (n)
if n == 0 then
return 1 else
return n*fact(n-1) -- buggy
end end

上面这种方式导致 Lua 编译时遇到 fact(n-1)并不知道他是局部函数 fact,Lua 会去查找是否有这样的全局函数 fact。为了解决这个问题我们必须在定义函数以前先声明:

local fact
fact = function (n)
if n == 0 then
return 1 else
return n*fact(n-1)
end
end

这样在 fact 内部 fact(n-1)调用是一个局部函数调用,运行时 fact 就可以获取正确的 值了。

但是 Lua 扩展了他的语法使得可以在直接递归函数定义时使用两种方式都可以。 在定义非直接递归局部函数时要先声明然后定义才可以:

local f, g -- `forward' declarations
function g ()
... f() ...
end
function f ()
... g() ...
end

10: 一个 list 写一个简单的迭代器

function list_iter (t)
local i = 0
local n = table.getn(t) --返回list的size
return function ()
i=i+1
if i <= n then return t[i] end
end
end

t = {10, 20, 30,5,6,7}
iter = list_iter(t) -- creates the iterator
while true do
local element=iter() --calls the iterator
if element == nil then
break
end

print(element)
end

我们设计的这个迭代器也很容易用于范性 for 语句

t = {10, 20, 30}
for element in list_iter(t) do
print(element)
end
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子认人晚上哭怎么办 主腹动脉有硬块怎么办 糖链抗原125偏高怎么办 狗长了个肿瘤怎么办 腺肌瘤糖类抗原125升高怎么办 糖类抗原724单项升高怎么办? 化疗期间糖类抗原升高怎么办? 门面租客到期不搬怎么办 这几天老想初恋怎么办 结婚了还想初恋怎么办 九年了想初恋了怎么办 吃肥肉恶心想吐怎么办 宝宝吃了母乳不吃奶粉怎么办 母猫的奶少怎么办 鲤鱼打挺起不来怎么办 练不会鲤鱼打挺怎么办 鲤鱼打挺脖子痛怎么办 新买的沙发太高怎么办 额最后离开公司没人关灯怎么办 看到我妹妹就烦怎么办 野塘钓鱼不开口怎么办 团关系找不到接收地怎么办 两岁宝宝就是不肯说话怎么办 两岁宝宝不肯吃药怎么办 并蹄莲叶子大黄怎么办 异地恋见面来大姨妈怎么办 奶水太多宝宝老是呛到怎么办 奶水太多吃奶婴儿呛怎么办 人家不愿意交我为朋友怎么办 面对诋毁我的人怎么办 做事太细致速度太慢怎么办 高一儿子早恋了怎么办 儿子18岁谈朋友怎么办 和朋友为钱吵架怎么办 感情里总担心失去怎么办 眼石移出盲僧怎么办 打仗把小便踢肿了怎么办 腿上都是挠的疤怎么办 脚上的肉烂了怎么办 商铺门口有电杆怎么办 漏电保护器坏了怎么办