Lua_Basics

Posted 程序员不是码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua_Basics相关的知识,希望对你有一定的参考价值。

最近看学习skynet框架,skynet中一般采用Lua来实现业务逻辑,也可用Lua来实现一些服务。因此准备学习一下Lua这门脚本语言,挑了《Programming in Lua这本开始啃了起来(英文原版)。并将一些值得mark的知识点总结记录了下来,一来加深理解,二来便于后续温故知新。不得不说这本书真的很赞,入门看它就够了,遇到一些不懂的接口,勤于查Lua官方文档。因此主要学习资料也就是一本书+官方文档即可。


1
Lua的基本类型


Lua的一些特点

  • Lua作为一门简单(Simplicity),可扩展(Extensibility),可移植(Portability),以及高效(Efficiency)的脚本语言,被应用在各个领域。(Lua是脚本语言中效率最高的)

  • Lua是一门动态语言:变量没有类型,变量的值才有类型。

  • Lua是一门解释性语言:生成字节码交由Lua虚拟机进行处理。(Python也是如此)


Lua一共有8中基本类型

  • nil任何全局变量在赋值前默认都是nil,可通过将一个变量赋值为nil来删除它

  • boolean: lua中只有false和nil为false,其他的都是true(包括0)

  • number: 包括整数和浮点数 注意0 == 0.0(true)

  • string:Lua中的string是不可变的(immutable)

  • userdata(内存块): 分为完全用户数据(由lua创建的内存并由lua进行gc)和轻量用户数据(由c/c++创建的内存,由c/c++释放)

  • function: Lua中到处都是函数,一个lua文件都可认为是一个匿名function

  • table: Lua中唯一也是最重要的数据结构

  • thread


Exercise

介绍一个计算阶乘的例子



2
strings



numbers内容比较简单,直接从string开始。


Lua中字符串是不可变的(immutable),我们不能改变字符串中的字符,一般会创建一个新的字符串来达到修改的目的,如下:

Lua_Basics


string.gsub用法总结

原型string.gsub(s, pattern, repl[,n])

功能:拷贝一份字符串s,并将s中出现的所有(或者n次,如果有)pattern替换成repl,返回两个参数,第一个为替换过后的字符串,第二个为替换字符串的次数。repl可为三种类型:string,table,function.

  • repl为string

    1. 为普通string,直接替换,如上string.gsub(s, "one", "another")

    2. %d形式,d可以为0-9,0代表整个匹配的字符串,否则代表第d个匹配的字符串

    Lua_Basics

  • repl为table

    会将匹配到的字符串作为key,根据key从table中取出value,再进行替换

    Lua_Basics

  • repl为function

    将匹配到字符串作为参数传递给function,并将function执行的返回结果进行替换

    Lua_Basics


长字符串表示

两种方式,第一种使用[=[ ... ]=], 第二种使用 进行换行,如下

Lua_Basics


字符串拼接(concatenation)

使用..进行拼接,拼接不会改变原有字符串(也不能改变,上述提到lua中string是不可变的)。

Lua_Basics

但是这种拼接方式是低效的,如果同时需要拼接多个字符串的话,因为每次拼接就意味着一次内存分配和字符串拷贝(其他脚本语言如python也同样有类似问题)。应当使用更为高效的字符串拼接方式table.concat,无论多少字符串,都只需要进行一次内存分配,每个带拼接的字符串也只需要拷贝一次。


string标准库

Lua的字符串库提供了丰富的函数,比如string.len, string.rep, string.reverse, string.lower, string.upper等,常用的字符串操作应该都可以满足,这里就不展开,在处理字符串的时候可以先看下Lib中是否已经实现了我们想要的功能,避免重复造轮子。


Exercise

1. 编写函数,实现在某个字符串的指定位置插入另外一个字符串

Lua_Basics

2. 编写函数,移除字符串中的指定部分(由起始位置和长度指定)

Lua_Basics

3. 判断是不是回文字符串,需要忽略空格和标点符号

Lua_Basics


3
Tables



Table是Lua中唯一的数据结构,但是Table非常灵活,基于Table可以实现其他编程语言中的所有数据结构,比如数组、集合、队列、栈等,甚至可以用Table来实现类。

  • 除了nil,Table可以用任何类型作为key。

  • 通过将Table中的key对应的value赋值为nil来删除Table中的key

  • 可以通过下标[]或者.来访问Table中的元素,比如a[x]a.x注意这两个代表的含义不同,前者变量x为key,后者字符串"x"作为key。

  • Table中第一个元素的下标从1开始

  • Table的创建很灵活,主要有两种方式,一种是list-style, 一种是record-style,比如:

    Lua_Basics

  • 使用Table实现列表时,我们把不包含nil的列表称为序列(sequence),只有序列用#来获取Table的长度才是准确的。我们可以利用#来向序列末尾插入一个元素,a[#a + 1] = v;如果不是序列,我们可以通过遍历table的方式计算table长度。


Table的三种遍历方式

Lua_Basics


如何高效访问嵌套Table

Lua_Basics


TODO

深入学习Table,需要搞懂以下问题

  • Lua源码中Table底层数据结构的实现(数组和哈希表),以及如何扩容,进而懂得如何使用table写出高效代码。

  • 元表如何来使用,__index__newindexrawgetrawset

这些进阶知识点后续会结合源码深入讲解。


Exercise

  1. 下列代码输出什么?(可帮助我们理解t.a和t[a]问题)
    Lua_Basics

  2. 编写函数,测试table是否为有效序列

    Lua_Basics

  3. table标准库提供了函数table.concat用于连接表中字符串;请实现自己的concat对比和table.concat的性能

    Lua_Basics


4
Functions



Lua中到处都是函数,甚至main.lua这种文件中的代码都可以看做是一个匿名函数。

可变参数函数

可以使用三个点...来表示可变参数

Lua_Basics

尾调用

尾调用不会保存调用函数的信息在栈上,比如:

Lua_Basics

Exercise

Lua_Basics


5
The External World



主要介绍IO模块,以及其他一些外部库,了解io.read, io.write, io.input, io.output, io.popen,  os.execute等一些接口。

io的默认输入为stdin,默认输出为stdout,通过使用io.inputio.output可以设置其输入输出方式。

本文主要介绍Lua中的几种重要类型,并通过一些实例来帮助理解这些类型结构,在阅读《Programming In Lua》时,一定要把课后题撸一遍,学习效果会更加明显。


参考:

http://www.lua.org/pil/

http://www.lua.org/manual/5.3/manual.html#lua_call

END



以上是关于Lua_Basics的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数