深入函数第一篇

  1. 函数是第一类值,具有特定的词法域

第一类值

  1. 第一类值的意思是函数与 lua 中的其他类型如数字,字符串具有相同的权力
  2. 函数可以存储到全局变量或局部变量变量,还可以存储到 table 中
  3. 可作为实参传递给其他函数,也可以作为其他函数的返回值

词法域

  1. 定义:一个函数可以嵌套在另一个函数中,内部函数可以访问外部函数定义的局部变量

  2. 函数与其他所有的值一样都是匿名的,没有名称

  3. 讨论print()函数时,相当于在讨论值仅为 print() 的变量

a = {p = print}
a.p("Hello World") -- Hello World
c = print
c("eee") -- eee
print = math.sin
a.p(print(math.pi / 2)) -- 1
sin = a.p
sin(10, 20) -- 10 20 function foo(x)
return 2 * x
end
-- 等价于
foo = function (x) return 2 * x end

匿名函数

  1. 一个函数定义可以是一条赋值语句,这样的函数表达式可以视为函数构造式,这种函数构造式的结果称为匿名函数
  2. 一般会将函数赋予全局变量
function foo(x)
return 2 * x
end
-- 等价于
foo = function(x) return 2 * x end

高阶函数

  1. 像 table.sort()这样的函数接收另一个函数作为实参的函数就称它为高阶函数
-- table.sort 对 table 中的所有元素进行排序
network = {
{name = "atest", IP = "255.255.255.0",}
{name = "btest2"}, IP = "255.255.255.1"},
{name = "ctest3"}, IP = "255.255.255.3"},
{name = "dtest4"}, IP = "255.255.255.4"},
}
table.sort(network,
function (a, b)
return (a.name > b. name)
end
)
-- 导数 (f(x + d) - f(x)) / d 函数在某一个点处的导数
function derivative (f, delta)
delta = delta or 1e-4
return function (x)
return (f(x + delta) - f(x)) / delta
end
end
-- sin 的导数是 cos
c = derivative(math.sin)
print(math.sin(1), c(1))
print(math.sin(1), math.cos(0))

闭合函数

names = {"Pe", "Tu", "Me"}
grades = {Pe = 10, Tu = 5, Me = 8}
table.sort(names, function (x, y)
return grades[x] > grades[y]
end
)
-- 按照年级进行排序
print(names[1], names[2], names[3]) function sortByGrade(names, grades)
table.sort(names, function (x, y)
return grades[x] > grades[y]
end
)
end
sortByGrade(names, grades)
  1. 匿名函数中调用外部函数的形参的变量称为非局部变量。
  2. 一个 closure 就是一个一个函数加上该函数所需访问的所有「非局部变量」
  3. 如果再次调用 newCounter ,那么他会创建一个新的局部变量 i 从而也会得到一个新的 closure
function newCounter()
local i = 0
return function ()
i = i + 1
return i
end
end
c1 = newCounter()
print(c1()) -- 1
print(c1()) -- 2 -- 重新定义 sin 函数,弧度转为角度
oldSin = math.sin
math.sin = function (x)
return oldSin(x * math.pi / 180)
end do
local oldSin = math.sin
local k = math.pi / 180
math.sin = function (x)
return oldSin(x * k)
end
end -- 限制一个程序访问文件
do
local oldOpen = io.open
local access_OK = function (filename, mode)
-- <检查访问权限的代码>
end
io.open = function (filename, mode)
if access_OK(filename, mode) then
print("允许访问")
return oldOpen(filename, mode)
else
print("不允许访问")
return nil, "access denied"
end
end
end

lua学习之深入函数第一篇的更多相关文章

  1. lua学习之深入函数第二篇

    深入函数 2 非全局的函数 函数是第一类值,函数可以存储到全局变量,局部变量,table 字段中 lua 函数库中的大部分函数存储到 table 字段中 Lib = {} Lib.foo = func ...

  2. lua学习之类型与值篇

    类型与值 lua 是动态类型的语言 在语言中没有类型定义的语法 每个值都携带有它的类型信息 8种基础类型 用 type 可以返回这个值的类型的名称 将一个变量用于不同类型,通常会导致混乱的代码 但合理 ...

  3. 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器

    × 目录 [1]id选择器 [2]元素选择器 [3]类选择器[4]通配选择器[5]群组选择器[6]后代选择器[7]兄弟选择器 前面的话 选择器是jQuery的根基,在jQuery中,对事件处理.遍历D ...

  4. Python学习之路【第一篇】-Python简介和基础入门

    1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...

  5. 任务驱动,Winform VS WEB对比式学习.NET开发系列第一篇------身份证解析(不断更新的WEB版本及Winform版本源码)

    一 本系列培训随笔适用人群 1. 软件开发初学者 2. 有志于转向Web开发的Winform程序员 3. 想了解桌面应用开发的Web程序员 二 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分 ...

  6. Lua学习笔记3. 函数可变参数和运算符、转义字符串、数组

    1. Lua函数可以接受变长数目的参数,和C语言类似,在函数的参数列表中使用(...)表示函数可以接受变长参数 lua函数将参数存放在一个table中,例如arg,那么#arg可以获得参数的个数 fu ...

  7. 华为LiteOS系统使用-任务调度函数-第一篇

    1.最近项目遇到华为的LiteOS小型操作系统,使用学习 2. 先打开一个工程LiteOS_Kernel-master\projects\LPC824_LITE_KEIL 3. main.c里面2个关 ...

  8. 浅聊本人学习React的历程——第一篇生命周期篇

    作为一个前端小白,在踏入前端程序猿行业的第三年接触了React,一直对于框架有种恐惧感,可能是对陌生事物的恐惧心里吧,导致自己一直在使用原生JS和JQ作为开发首选,但是在接触了React之后,发现了其 ...

  9. python之函数第一篇

    一.为什么用函数: 解决代码重用问题 统一维护 程序的组织结构清晰,可读性强二.定义函数 先定义后使用!! def funcname(arg1,arg2,...): """ ...

随机推荐

  1. mezzanine 历险记

    安装去github下载 mezzanine https://github.com/ganmk/mezzanine 安装出现问题了: grappelli_safe >= 0.4.5 问题好像出在这 ...

  2. 【WPF学习】第二十章 内容控件

    内容控件(content control)是更特殊的控件类型,它们可包含并显示一块内容.从技术角度看,内容控件时可以包含单个嵌套元素的控件.与布局容器不同的是,内容控件只能包含一个子元素,而布局容器主 ...

  3. Java容器解析系列(15) HashTable Dictionary & Properties

    HashTable的实现原理与HashMap没有什么区别; 其与HashMap的主要区别如下: 添加进入jdk时间:HashTable在jdk1.0时添加,HashMap在jdk1.2时添加; 类签名 ...

  4. ios--->cell里面 self 和self.contentview的区别

    一般我们向cell中添加子视图,有两种方式 [cell addSubview:] [cell.contentView addSubview:] 区别在于进行cell编辑时,比如cell内容向左移或者右 ...

  5. 为什么不在spring容器管理controller

    Spring容器与SpringMVC容器 1.疑问:为什么不用spring去管理所有类? 我们配置springMVC 中,为什么controller不直接交给spring 管理而要spring MVC ...

  6. Horizontal Pod Autoscaler(Pod水平自动伸缩)

    Horizontal Pod Autoscaler 根据观察到的CPU利用率(或在支持自定义指标的情况下,根据其他一些应用程序提供的指标)自动伸缩 replication controller, de ...

  7. Linux的总结

    Linux学习总结: 1.需要熟练掌握各种命令,这是保证工作效率的基础.经常使用的命令 1)tar 解压 2)pwd查看所在的根目录 3)mkdir touch cp cat... 4)   mv 移 ...

  8. 小白学习VUE第二课:环境搭建 VUE Node.js VSCode template模板

    环境搭建 VUE Node.js VSCode template模板: 首先安装node:http://www.runoob.com/nodejs/nodejs-install-setup.html ...

  9. Codeforces 1178E Archaeology (鸽巢原理)

    题意: 给你1e6的字符串,保证只含'a''b''c'三种字符,且相邻两个字符一定不一样 求一个大于等于n/2的回文子序列 思路: 朴素的最长回文子序列是n方的区间dp,这题显然不行,要充分利用题中所 ...

  10. POJ 1751 Highways(最小生成树Prim普里姆,输出边)

    题目链接:点击打开链接 Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has ...