lua程序设计第二版学习笔记

  脚本语言的基础语法大都比较简单,这里只列举一些lua独有,或者需要特别注意的语法点。

  书中前三章的内容是一些惯常的引言,基础数据类型,运算符等内容,相对简单,这里就不再赘述。

语句

  1、do...end 可以用来包含一个程序块。

  2、在循环语句中声明的局部变量,在条件判断时依然存在

  3、for循环分为数字型泛型

    数字型:

   for var=exp1, exp2, exp3 do
<执行体>
  end

  类似于C中将括号和句号去掉,var初始值为exp1,增长到exp2,步进为exp3。

  exp3可选,默认为+1,不设上限可将exp2设置为math.huge。

  for的控制变量会被自动声明为for的局部变量,无需单独声明,同时也无法在外部访问。

    泛型for:通过迭代器访问table

   for i,v in ipairs(a) do print(v) end    -- 打印所有值
  for k in pairs(t) do print(k) end -- 打印所有key

  4、lua中提供多种迭代器,也可自行编写

    迭代文件中的行 io.lines

    迭代table元素 pairs

    迭代数组元素 ipairs

    迭代字符串中单词 string.gmatch

  5、return ,break只能作为代码块的最后一条语句,或是end,else,until前的最后一条语句,否则lua语法报错,可以通过 do return end 显式包住一条return。

函数

6、lua中函数,若只有一个参数,且该参数为字面字符串或table构造式,函数的()可以省略。

7、lua为面向对象提供特殊语法——冒号操作符,将本身作为第一个值传入。

8、lua中函数可以返回多个值,同时用多个变量接受,类似于多重赋值,但是若函数调用不是一系列表达式的最后一个值,则只产生一个值

9、上一条中的现象,在多返回值函数作为另一个函数的非最后一个参数时也有效。

10、通过将函数调用放入一对圆括号中,可以迫使其之返回一个值。

11、unpack() 函数接受一个数组为参数,并且从下标1逐个返回所有参数,常用于泛型调用。

12、声明函数时,参数为(...),即为变长参数,在函数中 ‘...’ 被当作表达式使用。

13、变长参数和固定参数同时出现在函数参数中时,变长参数需放到最后。

14、当变长参数中含有故意传入的nil时,需要用select函数访问,select函数首先必须传入一个固定实参,如果这个实参为数字n,那么函数返回第n个变长参数(包括nil),否则变长参数必须为‘#’,返回变长数的总和。

15、具名函数,类似于python中指定函数参数赋值,但是需要把参数名和参数值写到一个table中,传入函数。

16、lua中的函数为第一类值,实际上将lua中的函数名理解为一个持有函数的变量更为合适。

1 function foo (x)  return *x end    等价于
foo = function (x) return *x end

   这使得lua可以轻松实现回调模式,例如C++中STL提供的排序函数,需要传入一个返回值为bool类型的函数指针,用以比较容器变量的大小,lua中可以这样实现,

   例如一个给table排序的函数:

 network = {............}
table.sort(network, function (a, b) return (a.id > b.id) end)

   对于这个特性的一个高阶应用,求导数:

  function derivative(f, delta)
 delta = delta or 1e-4
   return function(x)
return (f(x + delta) - f(x))/delta
end
end  c = derivate(math.sin)
 print(math.cos(), c())
  --> -0.83907152907645 -0.83904432662041

深入函数

  17、closure(闭合函数),从翻译上不太好理解这个概念。首先,在一个函数内部定义另一个函数时,那么内层的函数可以访问外层函数的变量,这项特征被称为“词法域”。而这个变量相对于内部的函数称为“非局部的变量”,一个closure就是一个函数加上该函数所需访问的所有非局部的变量。

  function newCount()
local i =
return function() i = i + return i end
end c1 = newCount()
print(c1()) --> 1
print(c1()) --> 2
c2 = newCount()
print(c2()) --> 1
print(c1()) --> 3
print(c2()) --> 2

  c1 和 c2是同一个函数所创建的两个不同的closure,他们各自拥有局部变量i的实例。

  18、closure的另一个用处是创建一个安全的沙盒环境去运行一些不受信任的代码。

 do
local oldOpen = oi.open
local access_OK = function(filename, mode)
<检查访问权限>
end
io.open = function(filename, mode)
if access_OK(filename, mode) then
return oldOpen(filename, mode)
else
return nil, "access denied"
end
end
end

  19、非全局函数,如某个table的成员或用local修饰了声明的函数,只有在当前块可以访问该函数。有一点需要注意,当定义递归的局部函数时,在递归时由于局部的函数尚未定义完毕,所以其实调用的是一个同名的全局函数,可以通过先定义一个局部的变量作为函数名来解决这个问题。

  20、对于非全局函数,lua中有一种语法糖:

 local function foo(<参数>) <函数体> end

  lua将其展开为:

 local foo
foo = function (<参数>) <函数体> end

  这样定义不会产生递归错误。当然对于间接递归这是无效的,间接递归必须一个前向声明,示例代码就不贴了,间接递归实在是种糟糕的语法,如非必要不要使用。

  21、尾调用,lua中正确的尾调用形式如下:

 return <function>(<args>)

  尾调用相当于一条goto语句,因为调用函数已经没有需要执行的代码,所以返回值可以直接被被调函数,也就是尾调用的函数返回值覆盖,此时递归的话不会产生栈溢出问题,同时也可以利用lua的这一特性实现状态机,用尾调用跳转到下一个状态,不会出现任何内存问题。

lua程序设计(一)的更多相关文章

  1. Lua程序设计之字符串精要

    (摘自Lua程序设计) 基本: Lua语言的字符串是一串字节组成的序列. 在Lua语言中,字符使用8个比特位来存储. Lua语言中的字符串可以存储包括空字符在内的所有数值代码,这意味着我们可以在字符串 ...

  2. Lua程序设计之数值

    (摘自Lua程序设计) 数值常量 从Lua5.3版本开始Lua语言为数值格式提供了两种选择:被称为integer的64位整形和被称为float的双精度浮点类型(注意,"float" ...

  3. 《Lua程序设计 第二版》学习笔记一

    Lua简介 Lua是一种简单.可拓展.可移植及高效的脚本语言. 开始 Lua之间不需要分隔符 运行方式: Linux下: lua -i prog dofile("lib1.lua" ...

  4. Lua程序设计入门

    在Lua中,一切都是变量,除了关键字.TTMD强大了. 1.注释 -- 表示注释一行 --[[ ]]表示注释一段代码,相当于C语言的/*....*/ 注意:[[ ... ]]表示一段字符串 2.lua ...

  5. lua元表和元方法 《lua程序设计》 13章 读书笔记

    lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...

  6. 关于Lua程序设计{读书笔记}

    1.lua中的标识符可以是由任意字母.数字和下划线构成的字符串,但不能以数字开头.2.lua将通常类似"_VALUE"的标识符作为保留标识符3.lua的保留字 and break ...

  7. Lua 程序设计 (Roberto,Ierusalimschy 著)

    1 开始 2 类型与值 3 表达式 4 语句 5 函数 6 深入函数 7 迭代器与泛型for 8 编译,执行与错误 9 协同程序(coroutine) 10 完整的示例 11 数据结构 12 数据文件 ...

  8. Lua程序设计(三)面向对象实现一个简单的类

    1.Lua面向对象实现步骤 ①创建一个全局表(称之为元表) ②设置这个元表的__index值(值通常为元表自己,这样就能通过__index查找到对应的属性和方法)__index 赋值其实是一个func ...

  9. Lua程序设计(二)面向对象概念介绍

    ----------------------------------------------------------- Lua面向对象3 local smartMan = { name = " ...

随机推荐

  1. ELK 学习笔记之 elasticsearch 版本控制

    版本控制: elasticsearch 版本控制: 内部版本控制 外部版本控制 内部版本控制: 内部版本会检查你提供的版本值和文档的版本值是否一致,如果不一致就报错,一致则可以更新. curl -XP ...

  2. Docker 学习笔记之 核心概念

    Docker核心概念: Docker Daemon Docker Container Docker Registry Docker Client 通过rest API 和Docker Daemon进程 ...

  3. MySQL-时区导致的时间前后端不一致

    背景 今天早上刚上班,就被同事提示,程序的日期处理有问题.数据库里日期为:2019-05-21 11:00:00 而前端显示的日期为:2019-05-21 16:00:00 分析 那肯定是和时区相关了 ...

  4. MySQL8身份验证问题解决

    开新项目.使用MySQL8,在经历过B级别的网速下载后,终于安装好了MySQL,虽然在终端上是可以直接登录的. 但是我使用Navicat就无法访问了,提示什么登录失败,还有乱码. 搜索了一下,发现是M ...

  5. Mariadb 基于Mycat实现读写分离

    环境:Mariadb主:192.168.200.129 Mariadb从:192.168.200.114 Mycat    :192.168.200.112 (1)      安装jdk,先查看本机是 ...

  6. Spring Boot (十五): 优雅的使用 API 文档工具 Swagger2

    1. 引言 各位在开发的过程中肯定遇到过被接口文档折磨的经历,由于 RESTful 接口的轻量化以及低耦合性,我们在修改接口后文档更新不及时,导致接口的调用方(无论是前端还是后端)经常抱怨接口与文档不 ...

  7. 微信开发中使用微信JSSDK和使用URL.createObjectURL上传预览图片的不同处理对比

    在做微信公众号或者企业微信开发业务应用的时候,我们常常会涉及到图片预览.上传等的处理,往往业务需求不止一张图片,因此相对来说,需要考虑的全面一些,用户还需要对图片进行预览和相应的处理,在开始的时候我使 ...

  8. SQL SERVER 还原误操作导致还原无法停止,处理办法

    昨天遇到运行库不知道单位哪个小伙子,把数据库还原了,导致单位业务全部瘫痪,主数据库一直显示正在还原,真的是不敢动,经过多方寻找,找到此脚本-------------------------数据库还原日 ...

  9. Redis之安装配置(Windows)

    下载 下载地址:https://github.com/MSOpenTech/redis/releases 解压,文件的名字重命名为redis. 打开文件夹,内容如下: 发送redis-server.e ...

  10. 主动降噪(Active Noise Control)

    智能耳机 人机交互 智能声学终端 智能耳机 智能音箱 智能听力器 喇叭单体 动圈喇叭 新材料 DLC 石墨烯 陶瓷单位 吸音材料 智能芯片 阵列式麦克风 声纹传感器 演算法 降噪算法 智能听力保护 A ...