Lua学习笔记-Day03

1、loadstring、dofile和loadfile的用法和区别:

(1)对loadstring,程序示例如下:

f = loadstring("i = i + 1")
i = 0
f()   print(i)
f()   print(i)

很明显,loadstring将一个语句块加载为一个函数,并返回这个函数。loadstring使用方便灵活,但是它的开销也比较大。

(2)dofile是用于加载并执行外部文件

dofile("F:\\LuaProject\\day01.lua")--加载并运行外部文件

要注意dofile里面要使用绝对路径。

(3)loadfile用于加载外部文件但不马上执行,等待调用。这是它与dofile的区别之处。

file = loadfile("F:\\LuaProject\\day01.lua") --加载外部文件,但并不马上执行
local func = assert(file)  --返回一个函数以供调用
func() --需要时就能调用

2、闭包:简单来说,闭包就是函数中的函数,外层为父函数,内层就是闭包。它最大的优点有两个,一是可以读取父函数的变量,二是将这些变量的值始终保存在内存中。示例代码如下:

function func(a)
    local a = a or 0
    local fun = function() --被嵌套的函数称为闭包
        a = a + 1
        print(a)
    end
    return fun
end

local func1 = func(3)
local func2 = func(10) --后面的参数不影响前面的参数,这是闭包的优点
for i = 1, 10 do
    func1()
    func2()
end

闭包与其他函数最大的区别是,两次调用函数,使用不同的参数时,前后互不影响。这样就可以实现只改变参数而使程序做出不同的行为。

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

协程创建:coroutine.create(),协程挂起:coroutine.yield()

协程状态:coroutine.status(),协程运行:coroutine.resume()

示例代码如下:

function coroutineFunc()
    local co = coroutine.create(  --创建一个协程,里面封装了一个匿名函数
        function(a , b)
            for i = 1, 2 do
                print(i.."  "..a+b)
                coroutine.yield() --协程挂起,每次循环都执行这个操作
            end
        end)
   
    return co   --返回这个协程
end

local co = coroutineFunc()
print(coroutine.status(co)) --打印协程的状态
coroutine.resume(co,3,6) --调用协程,需要传递给内部匿名函数两个参数
coroutine.resume(co,5,6) --调用多少次写多少遍,只有第一次传入的值是有效的
coroutine.resume(co,5,6)
--[[因为内部函数循环两次,这里是第三次调用,调用无任何输出,
但是调用完成后协程的状态变成dead]]
print(coroutine.status(co)) --打印协程的状态:dead

4、Lua中的链表。每个结点以一个table来表示,一个“链接”只是节点table中的一个字段,该字段包含了对其他table的引用。

--测试链表
list = {next = list, value = 1}
list = {next = list, value = 2}
list = {next = list, value = 3}
list = {next = list, value = 4}
list = {next = list, value = 5}
local l = list
while l do
    print(l.value)
    l = l.next
end

5、Lua 中的每个值都可以用一个 metatable。 这个 metatable 就是一个原始的 Lua table , 它用来定义原始值在特定操作下的行为。Lua在创建新table时不会创建元表。

metatable 中的键名为 事件 (event) ,把其中的值叫作 元方法 (metamethod)。可以通过 getmetatable 函数来查询到任何一个值的 metatable。可以通过 setmetatable 函数来替换掉 table 的 metatable 。但不能从 Lua 中改变其它任何类型的值的 metatable (使用 debug 库例外); 要这样做的话必须使用 C API 。

示例代码如下:

--[[下面这个 getbinhandler 函数定义了 Lua 怎样选择一个处理器来作二元操作。
 首先,Lua 尝试第一个操作数。 如果这个东西的类型没有定义这个操作的处理器,
然后 Lua 会尝试第二个操作数。 ]]
 function getbinhandler (op1, op2, event)
    return metatable(op1)[event] or metatable(op2)[event]
end
--op1 + op2 的行为
function add_event (op1, op2)
   local o1, o2 = tonumber(op1), tonumber(op2)
   if o1 and o2 then  -- 两个操作数都是数字?
     return o1 + o2   -- 这里的 '+' 是原生的 'add'
   else  -- 至少一个操作数不是数字时
     local h = getbinhandler(op1, op2, "__add")
     if h then
       -- 以两个操作数来调用处理器
       return h(op1, op2)
     else  -- 没有处理器:缺省行为
       error(···)
     end
   end
end
print(add_event(1,2))  --输出结果是3

6、Lua提供了一种可以改变table行为的方法。有两种方法可以改变table的行为:查询table及修改table中不存在的字段。实际上,当访问一个table中不存在的字段时,这些访问会促使解释器去查找一个叫做__index 的元方法,如果没有这个元方法,那么访问结果才为nil。验证代码如下:

--创建一个名字空间
Window = {}
--使用默认值创建一个原型
Window.prototype = {x = 0, y = 0, width = 100, height = 100}
Window.mt = {}--创建元表
--声明构造函数
function Window.new(o)
    setmetatable(o,Window.mt)
    return o
end
--定义__index元方法
Window.mt.__index = function(table, key)
    return Window.prototype[key]
end
--创建一个窗口,并查询一个它没有的字段
w = Window.new{ x = 10, y = 20}
print(w.width)--最后结果是100,证明w调用了它的元方法__index

7、单一方法:当对象只有一个方法时,可以不用创建接口table,但要将这个单独的方法作为对象表示来返回
function newObject(value)
    return function(action, v)
        if action == "get" then
            return value
        elseif action == "set" then
            value = v
        else error("error..............")
        end
    end
end

d = newObject(0)
print(d("get"))
d("set",10)
print(d("get"))

8、Lua数学库:三角函数:sin、cos、tan、asin、acos等

指数和对数函数:exp、log、log10

取整函数:floor、ceil

最大最小:max、min

随机数:random、randomseed

变量:pi、huge(Lua中可以表示的最大的数字)

所有的三角函数都使用弧度单位,可以用函数deg和rad来转换角度和弧度。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

  • 1.1程序块:Lua执行的每段代码,例如一个源代码文件或者交互模式中输入的一行代码,都称为一个程序块 1.2注释:...
    c_xiaoqiang阅读 2,585评论 0 9
  • “协程(coroutine)”于我而言还是比较新的概念,Lua 也是刚接触不久。不过碰巧这段时间我又在看 ES6 ...
    NARUTO_86阅读 1,689评论 0 3
  • 六月二十八日,我来到了广州伦教,体验了不一样的生活。 在这里有不一样的人,不一样的语言,不一样的生活习惯。在过几年...
    董睿扬阅读 419评论 0 3
  • 春日偶成 朝代:宋代 作者:程颢 原文: 云淡风轻近午天,傍花随柳过前川。 时人不识余心乐,将谓偷闲学少年。 这是...
    梦与七鹿阅读 1,185评论 0 0
  • 圈子是最好的老师。 你身边人有什么?就问身边人学什么。
    我心我愿秀阅读 134评论 0 2