lua 高级篇(一)

第六章: 再论函数

Lua 中的函数是带有词法定界(lexical scoping)的第一类值(first-class values)。
 第一类值指:在 Lua 中函数和其他值(数值、字符串)一样,函数可以被存放在变
                  量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。
词法定界指:被嵌套的函数可以访问他外部函数中的变量。这一特性给 Lua 提供了
                 强大的编程能力。

先给出一些实例,看看lua的函数是如何跟普通变量一样可以进行赋值 作为参数。。。

function foo(x) return x * 2 end

print(foo(3)) -- 6

a = {p = print}
a.p("hello world") -- hello world
print = math.sin -- print new refer to the sin function
a.p(print(1))
sin = a.p
sin(10,20) -- 10  20  funciton print

network = {
    {name = "grauna", IP = "210.26.30.34"},
    {name = "arraial", IP = "210.26.30.23"},
    {name = "lua", IP = "210.26.23.12"},
    {name = "derain", IP = "210.26.23.20"},
    }

table.sort( network, function (a,b) return (a.name > b.name) end) --没有名字的函数 匿名函数

1 闭包

当一个函数内部嵌套另一个函数时,内部的函数体可以访问外部的函数的局部变量,这种特征叫做词法界定。

names = {"Peter","Paul","Mary"}
grades={Mary=10,Paul=7,Mary=5}
table.sort(names,function (n1,n2)
    return grades[n1] > grades[n2]
end)

--实现上述功能函数

function sortBygrade(names,grades)
    table.sort(names,function (n1,n2)
        return grades[n1] > grades[n2] -- compare the grades
    end)
end

一个计数器的例子:

function newCounter()
    local i = 0
    return 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(math.sin(100))

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

print(math.sin(100))

2、非全局函数

Lua的函数可以作为全局变量也可以作为局部变量,函数使用table作用域, 有三种定义方式

-- 表和函数放在一起
Lib = {}

Lib.foo = function (x,y)
    return x + y
end

Lib.goo = function(x,y)
    return x - y
end

-- 使用表构造函数

Lib2 = {
    foo = function(x,y) return x + y end,
    goo = function(x,y) return x - y end
}

--定义方式三

function Lib.square(x)
    return 2 * x
end

function Lib.sqrt(x)
    return math.sqrt(x)
end

print(Lib.foo(2,3))
print(Lib2.goo(4,5))
print(Lib.square(2))
print(Lib.sqrt(3))

3、正确的尾调用

Lua函数的另外一个有趣的特征是可以正确的处理尾调用(proper tail recursion)

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

例如:

function f(x)
    return g(x)
end
时间: 2024-10-18 18:55:54

lua 高级篇(一)的相关文章

lua 高级篇(二)

第七章  迭代器与泛型for       迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素,在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素.    一.迭代器与闭包    一个简单的例子: 我们为一个list写一个简单的迭代器,与ipairs()不同的是我们实现的这个迭代器返回元素的值而不是索引下标: function list_iter(t) local i = 0 local n = table.getn(t) return function () i

Spark性能优化指南——高级篇

Spark性能优化指南--高级篇 [TOC] 前言 继基础篇讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化指南>的高级篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问题. 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数据倾斜发生时的现象 绝大多数tas

awk(四)高级篇

前面三篇总结了awk的基本结构,常用系统变量,流程控制,和函数. 这一篇总结下awk剩余的一些话题. getline函数 getline函数是从输入,标准输入,文件或管道读取另一行 getline和next有点类似,它俩都导致下一个输入行被读取.不同的,next语句将控制返回到脚本的顶部.而getline得到新的一行,但没有改变脚本的控制. next类似于sed中命令d. 而getline函数则类似于sed中命令N,不过和N还是有点小区别的. sed中的N命令,是读取新行,旧行和新行之间用换行符

PHP微信公众平台开发高级篇—微信JS-SDK

PHP微信公众平台开发高级篇—微信JS-SDK 第一步.绑定域名: 第二步.引入JS文件: 第三部.通过Config接口注入权限验证配置 第四部.通过Read接口处理成功验证 第五部.通过Error接口处理失败验证 实际案例:分享接口内容

《C#网络编程高级篇之网页游戏辅助程序设计(扫描版)》

<C#网络编程高级篇之网页游戏辅助程序设计>通过编写C#网络编程语言中具有代表性的实例,向读者深入细致地讲解了如何利用C#语言进行网页游戏辅助程序设计.本书通过大量的代码引导读者一步步学习和掌握C#的网络应用编程的方法和网页游戏辅助程序的设计技术. <C#网络编程高级篇之网页游戏辅助程序设计>涉及的领域包括多线程编程技术.socket套接字编程.tcp协议编程.http协议编程.远程控制技术.木马技术.模拟键盘和鼠标技术.网页游戏辅助程序设计技术等. <C#网络编程高级篇之网

在Eclipse中使用JUnit4进行单元测试(高级篇)【转】

通过前 2 篇文章,您一定对 JUnit 有了一个基本的了解,下面我们来探讨一下JUnit4 中一些高级特性. 一.     高级 Fixture 上一篇文章中我们介绍了两个 Fixture 标注,分别是 @Before 和 @After ,我们来看看他们是否适合完成如下功能:有一个类是负责对大文件(超过 500 兆)进行读写,他的每一个方法都是对文件进行操作.换句话说,在调用每一个方法之前,我们都要打开一个大文件并读入文件内容,这绝对是一个非常耗费时间的操作.如果我们使用 @Before 和 

【转载】Spark性能优化指南——高级篇

前言 数据倾斜调优 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 查看导致数据倾斜的key的数据分布情况 数据倾斜的解决方案 解决方案一:使用Hive ETL预处理数据 解决方案二:过滤少数导致倾斜的key 解决方案三:提高shuffle操作的并行度 解决方案四:两阶段聚合(局部聚合+全局聚合) 解决方案五:将reduce join转为map join 解决方案六:采样倾斜key并分拆join操作 解决方案七:使用随机前缀和扩容RDD进行join 解决方案八:多

FreeRTOS高级篇8---FreeRTOS任务通知分析

在FreeRTOS版本V8.2.0中推出了全新的功能:任务通知.在大多数情况下,任务通知可以替代二进制信号量.计数信号量.事件组,可以替代数长度为1的队列(可以保存一个32位整数或指针值),并且任务通知速度更快.使用的RAM更少!我在< FreeRTOS系列第14篇---FreeRTOS任务通知>一文中介绍了任务通知如何使用以及局限性,今天我们将分析任务通知的实现源码,看一下任务通知是如何做到效率与RAM消耗双赢的.        在<FreeRTOS高级篇6---FreeRTOS信号量

25个增强iOS应用程序性能的提示和技巧(高级篇)(2)

25个增强iOS应用程序性能的提示和技巧(高级篇)(2) 2013-04-16 14:56 破船之家 beyondvincent 字号:T | T 在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致用户的差评.然而由于iOS设备的局限性,有时候要想获得良好 AD:网+线下沙龙 | 移动APP模式创新:给你一个做APP的理由>> 25) 尽量避免Date格式化如果有许多日期需要使用NSDateFormatter,那么需要小心对待了.如