【数学库】

数学库(math)由一组标准的数学函数构成。这里主要介绍几个常用的函数,其它的大家可以自行百度解决。

  1. 三角函数(sin,cos,tan……)
    所有的三角函数都使用弧度单位,可以用函数deg(角度)和rad(弧度)来转换角度和弧度。示例代码:

    print(math.sin(math.rad())) -- 0.5

    谨记:三角函数的参数都是弧度,在实际使用中不要忘了,是弧度。

  2. 取整函数(floor,ceil)
    floor:返回不大于x的最大整数;向下取整;
    ceil:返回不小于x的最大整数;向上取整。示例代码:
    print(math.floor(5.6)) --
    print(math.ceil(5.6)) --
  3. 最大值和最小值(max,min)
    max:取参数中的最大值;
    min:取参数中的最小值。示例代码:
    print(math.max(, , , , , , -)) --
    print(math.min(, , , , , , -)) -- -3
  4. 生成伪随机数的函数(random,randomseed)
    在实际开发中,生成随机数的需求是经常有的。使用random和randomseed这两个函数就可以轻易的完成。math.random用于生成伪随机数,可以用3种方式来调用它:
    (1)如果在调用时不提供任何参数,它将返回一个在区间[0, 1)内均匀分布的伪随机实数;
    (2)如果提供了一个整数n作为参数,它将返回一个在区间[1, n]内的伪随机整数;
    (3)如果提供了两个整数参数m和n,它将返回一个在区间[m, n]内的伪随机整数。
    示例代码如下:

    print(math.random()) -- 输出一个大于等于0,小于1的值
    print(math.random()) -- 输出不是1就是2
    print(math.random(, )) -- 输出不是3就是4

    如果你按照上面的代码运行,然后再看着我写的注释,你可能就要骂我了,什么破注释了,明显就是错的么?每次运行的输出结果都是一样的。是的,结果是一样的,这就要说到即将出场的math.randomseed。函数math.randomseed用于设置伪随机数生成器的种子数。(看到这里,我姑且认为你是已经有过一年编程经验的人员了,所以,你就不要问我什么是种子了,这种概念性的东西,我想百度百科或者维基百科比我更有指导意义)math.randomseed的唯一参数就是一个我们称为种子数的值。一般我们的做法是在一个程序启动时,用一个固定的种子数来调用它,以此初始化伪随机数生成器。那么如何设置这个math.randomseed的种子值呢?如果使用同一个种子值的话,每次得到的随机数就会是一样的,在实际开发中,一般都是使用当前时间作为种子值,比如:

    math.randomseed(os.time())
    这样就好了。一般在我们的程序启动时,初始化一次种子就足够了。我曾经傻傻的在一个循环中,使用math.random取随机数,每次都调用math.randomseed(os.time())设置种子值(为什么不可以?你可以自己试一试,看看结果。如果不懂,留下你的迷惑,我们继续交流)。
    math.randomseed(os.time())
    print(math.random()) -- 输出一个大于等于0,小于1的值
    print(math.random()) -- 输出不是1就是2
    print(math.random(, )) -- 输出不是3就是4
    这样就好了,运行一下,看看结果吧。

【table库】

table库是由一些辅助函数构成的,这些函数将table作为数组来操作(重点:作为数组来操作的)。

  1. 插入和删除函数
    table.insert用于将一个元素插入到一个数组的指定位置,它会移动后续元素以空出空间。如果在调用table.insert时没有指定位置参数,则会将元素添加到数组末尾。示例代码:

    local tb = {, , }
    table.insert(tb, ) -- 在table的最后插入,结果为:{10, 20, 30, 40}
    table.insert(tb, , ) -- 在table的位置2插入,结果为:{10, 15, 20, 30, 40}
    函数table.remove会删除并返回数组指定位置上的元素,并将该位置之后的所有元素前移,以填补空缺。如果在调用这个函数时不指定位置参数,它就会删除数组的最后一个元素。示例代码:
    local tb = {, , }
    print(table.remove(tb)) -- 删除最后一个元素,并返回30;最后,tb = {10, 20}
    print(table.remove(tb, )) -- 删除第一个元素并返回10;最后,tb = {20}
    现在有了这两个操作,实现数据结构中的堆栈那就轻而易举了。等什么?自己试一试吧。
  2. 排序
    对数组进行排序,这种需求,在实际开发中那是100%会遇到的。所以了,不会使用Lua对数组进行排序,那是会被别人笑掉大牙的。废话少说。在Lua中,我们可以用table.sort完成这个任务。它可以对一个数组进行排序,还可以指定一个可选的次序函数。这个次序函数有两个参数,如果希望第一个参数在排序结果中位于第二个参数值前,就应当返回true;如果没有提供这个函数,table.sort就使用默认的小于操作。实例代码:
    local tb = {, , , , , , , , , }
    
    -- 默认是升序排序
    table.sort(tb)
    for _, v in ipairs(tb) do
    print(v)
    end print("=======") -- 修改为降序排序
    table.sort(tb, function (a, b) if a > b then return true end end)
    for _, v in ipairs(tb) do
    print(v)
    end
    但是,在实际开发中,我们经常犯这样的错误,总是试图对一个table的索引进行排序。在table中,索引是一个无序的集合。如果对它们进行排序,则必须将它们复制到一个数组中,然后对这个数组进行排序。这就是我为什么一开始强调的,table库是对数组进行操作的。示例代码:
    local tb = {x = , z = , y = , m = , n = } -- 这是一个key无序的table
    -- 如果想按照key的升序排列,下列代码是不起作用的
    table.sort(tb)
    for k, v in pairs(tb) do
    print(k .. " = " .. v)
    end
    正确做法是将这个table的所有key放入到一个数组中,对这个数组进行排序。示例代码:
    local tb = {x = , z = , y = , m = , n = } -- 这是一个key无序的table
    
    local keyTb = {}
    for k, _ in pairs(tb) do
    keyTb[#keyTb + ] = k
    end table.sort(keyTb) for _, v in ipairs(keyTb) do
    print(v .. " = " .. tb[v])
    end
    现在就是按照key的升序排列了。
  3. 连接
    使用table.concat可以完成数组的连接。它接受一个字符串数组,并返回这些字符串连接后的结果,它有一个可选参数,用于指定插到字符串之间的分隔符,同时这个函数另外还接受两个可选参数,用于指定第一个和最后一个要连接的字符串索引。示例代码:
    local tb = {"Jelly", "Think", "Is", "Good"}
    local strTb = table.concat(tb, " ")
    print(strTb)

【字符串库】

重点来了,学习每种语言,在实际工作时,我们总是在和字符串进行打交道。Lua也不例外,在Lua中真正的字符串操作能力来源于字符串库,字符串库中的所有函数都导出在模块string中。现在就来对string库进行总结。

    1. 基础字符串函数
      直接通过代码来说吧,示例代码:

      local str = "Jelly Think"
      
      -- string.len可以获得字符串的长度
      local len = string.len(str)
      print(len) -- -- string.rep返回字符串重复n次的结果
      str = "ab"
      local newStr = string.rep(str, ) -- 重复两次
      print(newStr) -- abab -- string.lower将字符串大写变成小写形式,并返回一个改变以后的副本
      str = "Jelly Think"
      newStr = string.lower(str)
      print(newStr) -- jelly think -- string.upper将字符串小写变成大写形式,并返回一个改变以后的副本
      newStr = string.upper(str)
      print(newStr) -- JELLY THINK
      这里重点介绍一下string.sub(s, i, j)函数,它可以从字符串s中提取第i个到第j个字符。在Lua中,字符串的第一个字符的索引是1,但是,索引也可以是负数,表示从字符串的尾部开始计数,索引-1代表字符串的最后一个字符,以此类推。
      local str = "[Jelly Think]"
      local newStr = string.sub(str, , -)
      print(newStr) -- Jelly Think
      newStr = string.sub(str, , )
      print(newStr) -- Jelly
      (重点:在Lua中,字符串和其它语言的一样,是不可变的,以上的操作,都会返回一个新的值,但并不会修改原来的字符串。谨记,谨记!!!)

      函数string.char和函数string.byte用于转换字符及其内部数值表示;string.char函数接受零个或多个整数,并将每个整数转换成对应的字符,然后返回一个由这些字符连接而成的字符串。string.byte(s, i)返回字符串s中第i个字符的内部数值表示,它的第二个参数是可选的,调用string.byte(s)可返回字符串s中第一个字符的内部数值表示。示例代码:

      print(string.char()) -- a
      
      local i =
      print(string.char(i, i + , i + )) -- bcd print(string.byte("abc")) --
      print(string.byte("abc", )) --
      print(string.byte("abc", , )) -- 98 99
      print(string.byte("abc", -)) --
      在Lua中也有一个神奇的函数,string.format。和C语言中的printf是一致的。之所以说它神奇,因为它用的太多了,也太好用了。以至于我这里就不多废话了,我相信你们都会的。
    2. 模式匹配
      由于模式匹配的东西比较多,所以,准备单独写篇博文单独总结。

【I/O库】

I/O库为文件操作提供了两种不同的模型,简单模型和完整模型。简单模型假设有一个当前输入文件和一个当前输出文件,它的I/O操作均作用于这些文件。完整模型则使用显式地文件句柄。它采用了面向对象的风格,并将所有的操作定义为文件句柄上的方法。

  1. 简单I/O模型

    简单模型的所有操作都作用于两个当前文件。I/O库将当前输入文件初始化为进程标准输入(stdin),将当前输出文件初始化为进程标准输出。在执行io.read()操作时,就会从标准输入中读取一行。
    用函数io.input和io.output可以改变这两个当前文件。io.input(filename)调用会以只读模式打开指定的文件,并将其设定为当前输入文件;除非再次调用io.input,否则所有的输入都将来源于这个文件;在输出方面,io.output也可以完成类似的工作。说完了input和output,在来聊聊io.write和io.read。

    io.write接受任意数量的字符串参数,并将它们写入当前输出文件;它也可以接受数字参数,数字参数会根据常规的转换规则转换为字符串。如果希望有更多的控制,可以使用string.format进行控制。函数io.read从当前输入文件中读取字符串,它的参数决定了要读取的数据:

    “*all” 读取整个文件
    “*line” 读取下一行
    “*number” 读取一个数字
    <num> 读取一个不超过<num>个字符的字符串

    直接看一段示例代码吧:

    -- 先建立input.txt和output.txt两个文件
    -- 在input.txt文件中写入以下内容:
    --[[
    http://www.jellythink.com
    果冻想 | 一个原创文章分享网站
    88
    --]]
    io.input("input.txt") -- 从input.txt文件中读取
    io.output("output.txt") -- 写入到output.txt文件 -- 向input.txt写入一些测试数据
    io.write("JellyThink", "\n")
    io.write("果冻想", "\n")
    io.write("http://www.JellyThink.com", "\n")
    io.write()
    读取一整个文件的示例代码:
    str = io.read("*all") -- 读取所有
    --[[
    print(str)
    http://www.jellythink.com
    果冻想 | 一个原创文章分享网站
    88
    --]]
    print(str)
    每次读取一行的示例代码:
    -- 用来判断是否已经读到了文件末尾
    -- 如果已经到了末尾,就返回nil;否则返回空字符串
    local mark = io.read()
    while mark do
    print(io.read("*line"))
    mark = io.read()
    if not mark then
    print("File end.")
    break
    end
    end
  2. 完整I/O模型
    简单I/O功能太受限了,以至于基本没有什么用处,而用的更多的则是这里说的完整I/O模型。完整I/O模型可以进行更多的I/O控制,它是基于文件句柄的,就好比与C语言中的FILE*,表示一个正在操作的文件。
    要打开一个文件,可以使用io.open函数,它有两个参数,一个表示要打开的文件名,另一个表示操作的模式字符串。模式字符串可以有以下四种取值方式:
    (1)”r”:以读取方式打开文件;只能对文件进行读取操作;
    (2)”w”:以写入方式打开文件;可以对文件进行写入操作,但是会覆盖文件原有内容;
    (3)”a”:以追加方式打开文件;可以对文件进行写入操作;会在原来文件的基础在,进行追加写入;
    (4)”b”:表示打开二进制文件,这种模式一般都是和前面三种混合使用,比如:”rb”,”wb”。

    open函数会返回表示文件的一个句柄;如果发生错误,就返回nil,一条错误消息和一个错误代码。示例代码:

    -- 访问一个不存在的文件
    print(io.open("ooxx.txt", r))
    --[[
    输出以下内容:
    nil ooxx.txt: No such file or directory 2
    --]]
    当成功打开一个文件以后,就可以使用read/write方法读写文件了,这与read/write函数相似,但是需要用冒号语法,将它们作为文件句柄的方法来调用,示例代码:
    local hFile = io.open("input.txt", r)
    if hFile then
    local strContent = hFile:read("*all")
    --local strContent = hFile.read(hFile, "*all") 你也可以使用这种方法
    print(strContent)
    end
    我们也可以将完整I/O模式与简单I/O模式混合使用。通过不指定参数调用io.input(),可以得到当前输入文件的句柄;而通过io.input(handle),可以设置当前输入文件的句柄,比如,需要临时改变当前输入文件,可以这样做:
    -- io.input()不传入参数时,获取当前的输入文件句柄
    local hCurrent = io.input() -- 打开一个新的文件
    io.input("input.txt") -- 在新的文件上进行操作
    local strContent = io.read("*all")
    print(strContent) -- 关闭当前文件
    io.input():close() -- 操作完成以后,恢复到以前的状态
    io.input(hCurrent)
  3. 其它文件操作
    函数tmpfile返回一个临时文件的句柄,这个句柄是以读/写方式打开;这个文件会在程序结束时自动删除。我们在使用时,可以直接io.tmpfile()就ok了。
    函数flush会将缓冲区中数据写入文件,它与write函数一样,将其作为一个函数调用时,io.flush()会刷新当前输出文件;而将其作为一个方法调用时,f:flush()会刷新某个特定的文件f。
    函数seek可以获取和设置一个文件的当前位置。它的一般形式是f:seek(whence, offset),其参数的具体含义如下:
    (1)whence取值set,offset表示为相对于文件起始的偏移量;
    (2)whence取值cur,offset表示为相对于当前位置的偏移量;
    (3)whence取值end,offset表示为相对于文件末尾的偏移量。

    函数的返回值与whence无关,它总是返回文件的当前位置,即相对于文件起始处的偏移字节数。根据上述的描述,来一小段示例代码:

    function GetFileSize(hFile)
    local currentPos = hFile:seek() -- 获取当前位置
    local size = file:seek("end") -- 获取文件大小
    file:seek("set", currentPos)
    return size
    end

Lua中的一些库(1)的更多相关文章

  1. Lua 中的string库(字符串函数库)总结

    (字符串函数库)总结 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-11-20我要评论 这篇文章主要介绍了Lua中的string库(字符串函数库)总结,本文讲解了string库 ...

  2. Lua中的一些库(2)

    [前言] 在<Lua中的一些库(1)>这篇文章中,总结了一部分Lua中的库函数,一篇文章肯定是总结不完的,所以,就来一个<Lua中的一些库(2)>.希望大家能忍住.来吧. 操作 ...

  3. Lua中的基本函数库--(转自忧郁的加菲猫)

    基本函数库为Lua内置的函数库,不需要额外装载assert (v [, message])功能:相当于C的断言,参数:v:当表达式v为nil或false将触发错误,message:发生错误时返回的信息 ...

  4. Lua中的基本函数库

    assert (v [, message])功能:相当于C的断言,参数:v:当表达式v为nil或false将触发错误,message:发生错误时返回的信息,默认为"assertion fai ...

  5. lua中的数学库

    Lua5.1中数学库的所有函数如下表: 使用数学库,不需要require,直接math.function就可以math.pi 为圆周率常量 = 3.14159265358979323846 abs 取 ...

  6. Lua中字符串库中的几个重点函数

    [前言] 在<Lua中的一些库(1)>中也说到了,要对string库的模式匹配进行单独的讲解.对于字符串的处理,对于任何语言的学习来说,都是一个难点,而且也是一个必会的知识点.给你一个字符 ...

  7. Lua中的常用函数库汇总

    lua库函数 这些函数都是Lua编程语言的一部分, 点击这里了解更多. assert(value) - 检查一个值是否为非nil, 若不是则(如果在wow.exe打开调试命令)显示对话框以及输出错误调 ...

  8. Lua中的字符串函数库

    字符串库中的一些函数是非常简单的: string.len(s)          返回字符串s的长度:string.rep(s, n)      返回重复n次字符串s的串:你使用string.rep( ...

  9. lua中的table、stack和registery

    ok,前面准备给一个dll写wrapper,写了篇日志,看似写的比较明白了,但是其实有很多米有弄明白的.比如PIL中使用的element,key,tname,field这些,还是比较容易混淆的.今天正 ...

随机推荐

  1. rocketmq 4.4部署安装

    官网下载:rocketmq-all-4.4.0-bin-release.zip 准备环境:centos7.6 Maven Java8+ 操作: 在工作目录中进行如下操作: /home/software ...

  2. html2canvas截屏在H5微信移动端踩坑,ios和安卓均可显示

    1.最近在做移动端开发,框架是vue,一产品需求是,后台返回数据,通过qrcode.js(代码比较简单,百度上已经很多了)生成二维码,然后通过html2canvas,将html元素转化为canvas, ...

  3. 双字节验证:vue输入框中英文字数长度验证

    export default { data() { let validcodeName=(rule,value,callback)=>{ //替换双字节汉字,为aa,限制输入框长度: if(va ...

  4. Static Sushi AtCoder - 4118 (技巧枚举)

    Problem Statement "Teishi-zushi", a Japanese restaurant, is a plain restaurant with only o ...

  5. JAVA关键字及作用

    ---恢复内容开始--- Java关键字及其作用 一. 总览: 访问控制 private protected public 类,方法和变量修饰符 abstract class extends fina ...

  6. Flask上下文管理源码分析 ——(3)

    引出的问题 Flask如何使用上下文临时把某些对象变为全局可访问 首先我们做如下的几种情况的假设 情况一:单进程单线程 这种情况可以基于全局变量存储临时的对象 情况二:单进程多线程 这种情况会出现多个 ...

  7. 如何给框架添加API接口日志

    前言 用的公司的框架,是MVC框架,看了下里面的日志基类,是操作日志,对增删改进行记录, 夸张的是一张业务的数据表 需要一张专门的日志表进行记录, 就是说你写个更新,添加的方法都必须写一遍操作日志,代 ...

  8. Django(一) 安装使用基础

    大纲 安装Django 1.创建Django工程 2.创建Django app 3.写一个简单的登录注册相应页面 4.获取用户请求信息并处理 5.前后端交互 6.Django 请求 生命周期  跳转到 ...

  9. win10安装ab测试工具

    1.先下载 https://www.apachehaus.com/cgi-bin/download.plx 2.存到非中文无空格的目录 3.解压,并打开配置文件:Apache24\conf\httpd ...

  10. Python——接口类、抽象类

    建立一个接口类.抽象类的规范 from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): # 元类 默认的元类 t ...