• Lua总结


    Lua总结

    • C语言做得很好的领域:性能、底层操作以及与第三方软件的接口
    • Lua语言提供C不善于的:高级语言、动态结构、简洁、易于测试和调试等。具有良好的安全保证,自动内存管理,简便的字符串处理功能及其它动态数据的改变。
    • Lua语言特征:
    1. 可扩展性:可通过Lua代码或C代码扩展,很多功能都是通过外部库来扩展的。
    2. 简单:小巧,内容少但功能强大
    3. 高效率:目前平均效率最高的脚本语言
    4. 与平台无关:可以运行任何平台,不是通过使用条件编译实现,而是完全使用ANST(ISO) C,意味着只要用ANST C编译器就可以编译并使用Lua
    • Lua的长处之一就是可以通过新类型和函数来扩展其功能。动态类型检查最大限度允许多态出现,并自动简化调用内存管理的接口,因为这样不需要关心谁来分配内存谁来释放内存,也不必担心数据溢出。高级函数和匿名函数均可以接受高级参数,使函数更为通用。
    • Lua可以调用lua或者C实现的函数,Lua所有标准库都是用C实现的。标准库包括String库、table库、I/O库、OS库、算术库、debug库。
    • userdata可以将C数据存放在Lua变量中,userdata在Lua中除了赋值和相等比较外没有预定义的操作。userdata用来描述应用程序或者使用C实现的库创建的新类型。

    uppack函数多值返回特殊函数,接受一个数组作为输入参数,返回数组的所有元素。uppack被用来实现范型调用机制。用递归循环参数个数返回。
    function unpack(t, i)
    i = i or 1
    if t[i] then
    return t[i], unpack(t, i + 1)
    end
    end

    Lua可接受可变数目的参数,使用三点(...)表示函数有可变的参数,Lua将函数的参数放在一个叫arg的表中,arg表中还有一个域n表示参数的个数。
    g(3) a=3, b=nil, arg={n=0}
    g(3, 4) a=3, b=4, arg={n=0}
    g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2}

    • Lua中的函数是带有词法定界的第一类值。
    • 第一类值指:在Lua中函数和其它值(数值、字符串)一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。
    • 词法定界指:嵌套的函数可以访问他外部函数中的变量。

    比如print,实际上是说一个指向函数的变量,像持有其它类型值的变量一样。
    a = {p = print}
    a.p("Hello World") --> Hello World
    既然函数是值,那么表达式也可以创建函数了,Lua中我们经常这样写:
    function foo (x) return 2*x end
    这实际上是Lua语法的特例,下面是原本的函数:
    foo = function (x) return 2*x end
    函数定义实际上是一个赋值语句,将类型为function的变量赋给一个变量。我们使用function (x) ... end来定义一个函数和使用{}创建一个表一样。

    • 闭包:是一个函数以及它的upvalue.
    • 词法定界指:当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部函数的局部变量。

    upvalue:sortbygrade函数内部的sort中的匿名函数可以访问sortbygrade的参数grades,在匿名函数内部grades不是全局变量也不是局部变量,我们称为外部的局部变量(external local variable)或者upvalue。
    function sortbygrade (names, grades)
    table.sort(names, function (n1, n2)
    return grades[n1] > grades[n2] -- compare the grades
    end)
    end
    c1、c2是建立在同一个函数上,但作用在同一个局部变量的不同实例上的两个不同的闭包。
    function newCounter()
    local i = 0
    return function() -- anonymous function
    i = i + 1
    return i
    end
    end

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

    • 闭包在上下文环境中提供很有用的功能,如作为函数嵌套的函数(newCounter)。这一机制使得可以在Lua的函数世界组合出奇幻的编程技术。闭包也可用在回调函数中,Button实际上是一个闭包,因为访问upvalue digit,digitButton完成任务返回后,局部变量digit超出范围,回调函数仍然可以被调用并且可以访问局部变量digit.

    function digitButton (digit)
    return Button{ label = digit,
    action = function ()
    add_to_display(digit)
    end
    }
    end

    • 闭包在不同上下文也有用途,因为函数被存储在普通的变量内可以方便看定义或者预定义函数。通常需要原始函数有一个新的实现时可以重定义函数。比如可以使用闭包重定义io库的open函数来限制程序打开的文件。

    oldSin = math.sin
    math.sin = function (x)
    return oldSin(x*math.pi/180)
    end

    • 尾调用是一种类似在函数结尾的goto调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。

    function f(x)
    return g(x)
    end
    g的调用是尾调用。可以将尾调用理解成一种goto,在状态机的编程领域尾调用是非常有用的。

    • 迭代器:是一种支持指针类型的结构,可以遍历集合的每一个元素。可以使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素。需要保留上一次成功调用的状态和下一次成功调用的状态,也就是知道来自于哪里和将要前往哪里。闭包提供的机制可以容易实现这个任务。记住:闭包是一个内部函数,可以访问一个或者多个外部函数的外部局部变量。每次闭包的成功调用后这些外部局部变量都保存他们的值(状态)。所以一个典型的闭包结构包含两个函数:一个是闭包自己;另一个是工厂(创建闭包的函数)。
    • 编译、运行、错误信息:虽然我们把Lua当作解释型语言,但是Lua会首先把代码预编译成中间码然后再执行(很多解释型语言都是这么做的)。在解释型语言中存在编译阶段听起来不合适,然而,解释型语言的特征不在于他们是否被编译,而是编译器是语言运行时的一部分,所以,执行编译产生的中间码速度会更快。我们可以说函数dofile的存在就是说明可以将Lua作为一种解释型语言被调用。

    dofile,把它当作Lua运行代码的chunk的一种原始的操作。dofile实际上是一个辅助的函数。真正完成功能的函数是loadfile;与dofile不同的是loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码;另外loadfile不会抛出错误信息而是返回错误码。完成简单的功能dofile比较方便,他读入文件编译并且执行。然而loadfile更加灵活。在发生错误的情况下,loadfile返回nil和错误信息,这样我们就可以自定义错误处理。另外,如果我们运行一个文件多次的话,loadfile只需要编译一次,但可多次运行。dofile却每次都要编译。

    require:Lua提供高级的require函数来加载运行库。粗略的说require和dofile完成同样的功能但有两点不同:
    1. require会搜索目录加载文件
    2. require会判断是否文件已经加载避免重复加载同一文件。由于上述特征,require在Lua中是加载库的更好的函数。

    • 协同程序:非抢占式的多线程,可以处理一边读一边写。每一个协同等同于一个线程,yield-resume可以实现在线程中切换。然后与真正的多线程不同的是协同是非抢占式的。

    对非抢占式多线程来说,只要有一个线程调用一个阻塞操作(blocking operation),整个程序在阻塞操作完成之前都将停止。

    • 数据结构:table是Lua中唯一的数据结构,在C语言经常使用(arrayst和lists)来实现大部分的数据结构。
    • 数组:初始化数组的时候间接定义了数组的大小,数组大小不固定,可动态增长。

    Metatables and Metamethods:任何一个表可以是其它一个表的metatable,一组相关的表可以共享一个metatable(描述他们共同的行为)。一个表也可以是自身的metatable(描述其私有行为)。元表作用:可以重定义新的运算。
    Metamethod原则:如果第一个参数存在带有_add域的metatable,Lua使用它作为metamethod,和第二个参数无关;

    • 面向对象:继承使得类可以访问其它类的方法。

    Lua中的对象不是元生的,所以有多种方法可以实现面向对象程序设计。index和metamethod是简洁、性能、灵活综合最好的。
    实现的关键在于:将函数用作_index,记住一个表的metatable存在一个_index函数时,如果Lua调用一个原始表中不存在的函数,Lua将调用这个_index指定的函数,这样可以用_index实现多个父类中查找子类不存在的域。
    多重继承意味一个类拥有多个父类,所以不能创建一个类的方法去创建子类。而是定义一个特殊的函数createClass来完成这个功能,将被创建的新类的父类作为这个函数的参数。

  • 相关阅读:
    多表联合查询,利用 concat 模糊搜索
    order by 中利用 case when 排序
    Quartz.NET 3.0.7 + MySql 动态调度作业+动态切换版本+多作业引用同一程序集不同版本+持久化+集群(一)
    ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述
    ASP.NET Core 2.2 基础知识(十七) SignalR 一个极其简陋的聊天室
    ASP.NET Core 2.2 基础知识(十六) SignalR 概述
    ASP.NET Core 2.2 基础知识(十五) Swagger
    ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
    linux磁盘管理 磁盘查看操作
    linux磁盘管理 文件挂载
  • 原文地址:https://www.cnblogs.com/wwhhgg/p/12604982.html
Copyright © 2020-2023  润新知