《Lua程序设计》--学习3

这篇具有很好参考价值的文章主要介绍了《Lua程序设计》--学习3。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

输入输出

简单I/O模型

Lua 文件 I/O | 菜鸟教程 (runoob.com)

对于文件操作来说,I/O库提供了两种不同的模型。简单模型虚拟了一个当前输入流(current input stream)和一个当前输出流(current output stream),其I/O操作是通过这些流实现的。I/O库把当前输入流初始化为进程的标准输入(C语言中的stdin),将当前输出流初始化为进程的标准输出(C语言中的stdout)。因此,当执行类似于io.read()这样的语句时,就可以从标准输入中读取一行。

函数io.input和函数io.output可以用于改变当前的输入输出流。调用io.input(filename)会以只读模式打开指定文件,并将文件设置为当前输入流。之后,所有的输入都将来自该文件,除非再次调用io.input。对于输出而言,函数io.output的逻辑与之类似。如果出现错误,这两个函数都会抛出异常。如果想直接处理这些异常,则必须使用完整I/O模型。

与函数print不同,函数io.write不会在最终的输出结果中添加诸如制表符或换行符这样的额外内容。

 函数io.write在将数值转换为字符串时遵循一般的转换规则;如果想要完全地控制这种转换,则应该使用函数string.format:

《Lua程序设计》--学习3

函数io.read可以从当前输入流中读取字符串,其参数决定了要读取的数据:

《Lua程序设计》--学习3

调用io.read("a")可从当前位置开始读取当前输入文件的全部内容。如果当前位置处于文件的末尾或文件为空,那么该函数返回一个空字符串。

因为Lua语言可以高效地处理长字符串,所以在Lua语言中编写过滤器(filter)的一种简单技巧就是将整个文件读取到一个字符串中,然后对字符串进行处理,最后输出结果为:

 《Lua程序设计》--学习3

作为面向行的(line-oriented)输入的一个简单例子,以下的程序会在将当前输入复制到当前输出中的同时对每行进行编号:

《Lua程序设计》--学习3

《Lua程序设计》--学习3

函数read会从输入流中读取n个字符。如果无法读取到任何字符(处于文件末尾)则返回nil;否则,则返回一个由流中最多n个字符组成的字符串。

《Lua程序设计》--学习3

io.read(0)是一个特例,它常用于测试是否到达了文件末尾。如果仍然有数据可供读取,它会返回一个空字符串;否则,则返回nil。

完整I/O模型

简单I/O模型对简单的需求而言还算适用,但对于诸如同时读写多个文件等更高级的文件操作来说就不够了。对于这些文件操作,我们需要用到完整I/O模型。

可以使用函数io.open来打开一个文件,该函数仿造了C语言中的函数fopen。这个函数有两个参数,一个参数是待打开文件的文件名,另一个参数是一个模式(mode)字符串。模式字符串包括表示只读的r、表示只写的w(也可以用来删除文件中原有的内容)、表示追加的a,以及另外一个可选的表示打开二进制文件的b。函数io.open返回对应文件的流。当发生错误时,该函数会在返回nil的同时返回一条错误信息及一个系统相关的错误码:

《Lua程序设计》--学习3

检查错误的一种典型方法是使用函数assert:

《Lua程序设计》--学习3

如果函数io.open执行失败,错误信息会作为函数assert的第二个参数被传入,之后函数assert会将错误信息展示出来。

在打开文件后,可以使用方法read和write从流中读取和向流中写入。它们与函数read和write类似,但需要使用冒号运算符将它们当作流对象的方法来调用。例如,可以使用如下的代码打开一个文件并读取其中所有内容:

《Lua程序设计》--学习3

如果想要临时改变当前输入流,可以像这样:

《Lua程序设计》--学习3

注意,io.read(args)实际上是io.input():read(args)的简写,即函数read是用在当前输入流上的。同样,io.write(args)是io.output():write(args)的简写。

补充知识

局部变量和代码块

Lua语言中的变量在默认情况下是全局变量,所有的局部变量在使用前必须声明

在交互模式中,每一行代码就是一个代码段(除非不是一条完整的命令)。一旦输入示例的第二行(local i=1),Lua语言解释器就会直接运行它并在下一行开始一个新的代码段。这样,局部(local)的声明就超出了原来的作用范围。解决这个问题的一种方式是显式地声明整个代码块,即将它放入一对do–end中。一旦输入了do,命令就只会在遇到匹配的end时才结束,这样Lua语言解释器就不会单独执行每一行的命令

《Lua程序设计》--学习3

注意这里x的范围 

《Lua程序设计》--学习3

 好处:局部变量可以避免由于不必要的命名而造成全局变量的混乱;其次,局部变量还能避免同一程序中不同代码部分中的命名冲突;再次,访问局部变量比访问全局变量更快;最后,局部变量会随着其作用域的结束而消失,从而使得垃圾收集器能够将其释放。

如果一个声明中没有赋初值,则变量会被初始化为nil

Lua语言中的一种常见用法:

《Lua程序设计》--学习3

这段代码声明了一个局部变量foo,然后用全局变量foo对其赋初值(局部变量foo只有在声明之后才能被访问)。这个用法在需要提高对foo的访问速度时很有用。当其他函数改变了全局变量foo的值,而代码段又需要保留foo的原始值时,这个用法也很有用,尤其是在进行运行时动态替换(monkey patching,猴子补丁)时。即使其他代码把print动态替换成了其他函数,在local print=print语句之前的所有代码使用的还都是原先的print函数。

在需要时才声明变量可以避免漏掉初始化这个变量

 控制结构

所有的控制结构语法上都有一个显式的终结符:end用于终结ifforwhile结构,until用于终结repeat结构。

Lua语言将所有不是false和nil的值当作真(特别地,Lua语言将0和空字符串也当作真)。

if then else

《Lua程序设计》--学习3

 如果要编写嵌套的if语句,可以使用elseif。它类似于在else后面紧跟一个if,但可以避免重复使用end

《Lua程序设计》--学习3

 while

当条件为真时while循环会重复执行其循环体。Lua语言先测试while语句的条件,若条件为假则循环结束;否则,Lua会执行循环体并不断地重复这个过程

repeat

repeat–until语句会重复执行其循环体直到条件为真时结束。由于条件测试在循环体之后执行,所以循环体至少会执行一次。

《Lua程序设计》--学习3

 和大多数其他编程语言不同,在Lua语言中,循环体内声明的局部变量的作用域包括测试条件

《Lua程序设计》--学习3

 数值型for

for语句有两种形式:数值型(numerical)for和泛型(generic)for。

《Lua程序设计》--学习3

 在这种循环中,var的值从exp1变化到exp2之前的每次循环会执行something,并在每次循环结束后将步长(step)exp3增加到var上。第三个表达式exp3是可选的,若不存在,Lua语言会默认步长值为1。如果不想给循环设置上限,可以使用常量math.huge:

《Lua程序设计》--学习3

 首先,在循环开始前,三个表达式都会运行一次;其次,控制变量是被for语句自动声明的局部变量,且其作用范围仅限于循环体内。一种典型的错误是认为控制变量在循环结束后仍然存在:

《Lua程序设计》--学习3

 如果需要在循环结束后使用控制变量的值(通常在中断循环时),则必须将控制变量的值保存到另一个变量中:

《Lua程序设计》--学习3

 泛型for

泛型for遍历迭代函数返回的所有值,例如我们已经在很多示例中看到过的pairs、ipairs和io.lines等。虽然泛型for看似简单,但它的功能非常强大。使用恰当的迭代器可以在保证代码可读性的情况下遍历几乎所有的数据结构。

与数值型for不同,泛型for可以使用多个变量,这些变量在每次循环时都会更新。当第一个变量变为nil时,循环终止。像数值型for一样,控制变量是循环体中的局部变量,我们也不应该在循环中改变其值。

break,return和goto

我们可以使用break语句结束循环,该语句会中断包含它的内层循环(例如for、repeat或者while);该语句不能在循环外使用。break中断后,程序会紧接着被中断的循环继续执行。

return语句用于返回函数的执行结果或简单地结束函数的运行。所有函数的最后都有一个隐含的return,因此我们不需要在每一个没有返还值的函数最后书写return语句。

goto

在Lua语言中,goto语句的语法非常传统,即保留字goto后面紧跟着标签名,标签名可以是任意有效的标识符。标签名称前后各紧跟两个冒号,形如::name::

在使用goto跳转时,Lua语言设置了一些限制条件。首先,标签遵循常见的可见性规则,因此不能直接跳转到一个代码块中的标签(因为代码块中的标签对外不可见)。其次,goto不能跳转到函数外(注意第一条规则已经排除了跳转进一个函数的可能性)。最后,goto不能跳转到局部变量的作用域。

《Lua程序设计》--学习3

 Lua语言规范中一个很有用的细节是,局部变量的作用域终止于声明变量的代码块中的最后一个有效(non-void)语句处,标签被认为是无效(void)语句。

读者可能认为,这个goto语句跳转到了变量var的作用域内。但实际上这个continue标签出现在该代码块的最后一个有效语句后,因此goto并未跳转进入变量var的作用域内。

有趣的代码:

《Lua程序设计》--学习3文章来源地址https://www.toymoban.com/news/detail-477130.html

到了这里,关于《Lua程序设计》--学习3的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《Lua程序设计》--学习3

    Lua 文件 I/O | 菜鸟教程 (runoob.com) 对于文件操作来说,I/O库提供了两种不同的模型 。简单模型虚拟了一个当前输入流(current input stream)和一个当前输出流(current output stream),其I/O操作是通过这些流实现的。I/O库把当前输入流初始化为进程的标准输入(C语言中的stdin),将当

    2024年02月08日
    浏览(40)
  • 《Lua程序设计》--学习2

    Lua语言中的 表 本质上是一种 辅助数组 (associative array),这种数组不仅可以使用数值作为索引,也可以使用字符串或其他任意类型的值作为索引(nil除外)。 当调用函数math.sin时,我们可能认为是“调用了math库中函数sin”;而对于Lua语言来说,其实际含义是“以字符串\\\"s

    2024年02月08日
    浏览(84)
  • 《Lua程序设计》--学习4

    在Lua语言中,函数是严格遵循词法定界(lexicalscoping)的 第一类值 (first-classvalue)。 “第一类值”意味着Lua语言中的函数与其他常见类型的值(例如数值和字符串)具有同等权限:一个程序可以将某个函数保存到变量中(全局变量和局部变量均可)或表中,也可以将某个函

    2024年02月08日
    浏览(81)
  • 《Lua程序设计第四版》 第一部分自做练习题答案

    Lua程序设计第四版第一部分语言基础自做练习题答案,带⭐为重点。 运行阶乘的示例并观察,如果输入负数,程序会出现什么问题?试着修改代码来解决问题 输入负数,程序会死循环,修改如下 分别使用-l参数和dofile运行twice示例,并感受你喜欢哪种方式 载入库,在 lua解释

    2024年02月13日
    浏览(53)
  • 《Lua程序设计第四版》 第二部分14~17章自做练习题答案

    Lua程序设计第四版第二部分编程实操自做练习题答案,带⭐为重点。 该函数用于两个稀疏矩阵相加 改写队列的实现,使得当队列为空时两个索引都返回0 修改图所用的数据结构,使得图可以保存每条边的标签。该数据结构应该使用包括两个字段的对象来表示每一条边,即边的

    2024年02月13日
    浏览(49)
  • 《Lua程序设计第四版》 第二部分9~13章自做练习题答案

    Lua程序设计第四版第二部分编程实操自做练习题答案,带⭐为重点。 请编写一个函数integral,该函数以一个函数f为参数并返回其积分的近似值 使用右矩阵法近似积分值 如下代码段将输出什么结果 编写练习5.4的柯里化版本 柯里化(Currying)是把接受 多个参数 的函数变换成

    2024年02月13日
    浏览(88)
  • 《Lua程序设计第四版》 第一部分前8章自做练习题答案

    Lua程序设计第四版第一部分语言基础自做练习题答案,带⭐为重点。 运行阶乘的示例并观察,如果输入负数,程序会出现什么问题?试着修改代码来解决问题 输入负数,程序会死循环,修改如下 分别使用-l参数和dofile运行twice示例,并感受你喜欢哪种方式 载入库,在 lua解释

    2024年02月13日
    浏览(162)
  • Java程序设计入门教程--控制台输入数据

    控制台输入数据常用类 Scanner类        在 很多情况下,我们需要 Java 程序能够对我们指定的值进行计算,这样的话就需要我们的 Java 程序能够读取我们所输入的值。我们可以使用 Java 自带的 Scanner 类来从控制台获取 输入 。        Scanner 类在包 java.util 里。我们一般在程

    2024年02月07日
    浏览(44)
  • C++学习第二十天----简单文件输入/输出

    1.写入到文本文件中         必须声明自己的ofstream对象,为其命名,并将其同文件关联起来;         方法open()接受一个c-风格字符换作为参数,可以是一个字面字符串,也可以是存在数组中的字符串。         声明一个ofstream对象并将其同文件关联起来后,用于

    2024年02月11日
    浏览(43)
  • 设计一个C51程序,使用定时器定时1s,输出周期为2s的方波

    结果显示: 定时器定时1s,输出周期为2s的方波,即产生1s的中断,每过1s方波翻转一次,周期是2s. 首先设置TMOD寄存器,GATE0 = 0使T0仅由TR0控制,C/ = 0,定时器模式,M0、M1 = 01方式1,TMOD = 0x01; 此实验中晶振振荡频率11.0592MHz,定时10ms,每100次P0取反,时隔1s 公式:定时时间 = (216 - X) *12 / 11.0592

    2024年02月08日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包