天天动画片 > 八卦谈 > Lua 是怎样一门语言?

Lua 是怎样一门语言?

八卦谈 佚名 2023-04-21 09:23:46

全部回答:
https://www.zhihu.com/question/19841006

皮皮关的回答:
https://www.zhihu.com/question/19841006/answer/1432644108


以下内容为对知乎答主皮皮关内容的搬运(部分对Aegisub开发比较核心的地方会用红色标注):


首先,Lua是一种在游戏开发领域非常常用的语言。

(1)魔兽世界客户端、大话西游2等知名网游中有Lua的身影。

(2)现代众多热更新手游也常用Lua写游戏逻辑,便于做热更新。

(3)Lua在skynet等现代网络游戏框架中有广泛应用。


1、Lua很小,语法极精简,但功能一点不少

Lua用纯C语言编写而成,兼容极为多样的平台包括某些单片机平台。

整个Lua语言的C语言源代码仅有2万行出头,这2万行代码包含了完整的编译器、虚拟机等等。

Lua仅有21个关键字。相比之下,连老版本(C89)的C语言都有32个关键字。

在如此精简的语法基础上,Lua实现了过程式编程、函数式编程、面向对象编程(包括封装、继承和多态)等等常用编程范式,且对闭包与协程都有极为完善的实现。


2、Lua语法过于灵活,不宜作为第一门编程语言学习

Lua实现了众多神奇功能的背后,离不开“表”(Table)这种数据结构,以及一些奇妙的设计。举一些例子:


(1)在Lua中,未使用过的变量值为nil

我们知道,绝大多数语言读取未定义或未使用过的变量,都会报错。但Lua不会,所有的变量初次读取不会报错,值为nil。

写错变量名是人之常情,对新手来说找手误bug是一种挑战  :)

(2)在Lua中,不加local关键的变量默认是全局变量

在实践中,建议给所有变量加上local,除非你确认一定需要全局变量。不加local所造成的奇怪bug会让你终身难忘  :)

(3)lua的逻辑运算符and、or

lua中,逻辑为假的值只有两个:nil和false;其它所有值包括数字0,都是真。

A and B:如果A为真,返回B;如果A为假,返回A。

A or B:如果A为真,返回A;如果A为假,返回B。

这种设计会让不熟悉逻辑运算的同学一头雾水,但逻辑上是自洽的。Lua的这种设计带来一些巧妙的用法:

(4)神奇的Lua Table

Lua的table容器是一种万能容器,可以用来作为:

①列表

②字典

③嵌套的列表和字典

④程序集(库)

⑤对象


在基本的表操作中,加入元表(metatable)之后,能支持更多特性:

①类的继承

②多态

③多重继承


元表是一种极为灵活的语法,利用元表甚至能修改Lua的基本语义,例如改变赋值的作用。

从教学的角度讲,Lua不宜作为第一门编程语言。但在有一定编程基础以后,通过类比学习Lua能起到举一反三的效果~~~


3、Lua具有极为优良的嵌入特性

(下面的内容是之前另一个问题的答案,比较有价值所以摘抄如下。参考原链接:zhihu.com/question/2171

下面我会揭示游戏程序框架与Lua关系一个关键的方面。

和所有人一样,我曾经认为所有脚本语言能嵌入到引擎中都是一样的。直到引擎架构足够复杂的时候,才发现了区别。在将脚本嵌入到本身就要处理多进程、多线程的框架之中时,脚本本身的架构会造成根本性差异,以下讨论都是针对这一点说的

首先对比一下Lua和Python的代码规模:

(1)Python完整C语言代码,约57万行

(2)Python核心C语言代码,约17万行

(3)Lua的所有C语言代码,约2万行


放心,我不是来说Lua有多么简洁多么美妙,问题不在这里。问题是:为什么Lua这么短?

任何一种程序,它所包含的逻辑功能大致和源码规模是相关的。任何一种实用性的语言都不可能比Lua的源码规模更小,而且未来Lua也不会变大很多,原因是——Lua严格限制了自己要解决的问题,从而把语言特性限制在一个非常有限的范围之内

其实要说Python等其它动态语言,谁也没想让自己变得臃肿(又不是Windows),但是事情并不总能按照想象的发展。根源在于虚拟机的框架设计主导了语言未来的走向,这里比较一下在C语言中初始化Python和Lua的方法:

初始化Lua环境(2个独立环境):

初始化Python环境:

看看注释,区别显而易见。大部分语言的虚拟机设计的目的是为了直接解决实际问题的,所以希望虚拟机能够独立运行,这就与线程、进程等等操作系统功能发生了直接联系。

比如Python环境就直接是全局变量,导致你无法在C里面优雅地使用一个沙盒式的Python环境,也就是说Python环境和C代码的部分理论上来讲是毫无分隔的。

而Lua虚拟机,不准确的说,和线程、进程关系都不大,一开始就把自己摘的干干净净,没规定1个进程只有一个Lua虚拟机,也没规定一个线程只执行一个Lua虚拟机,X个进程Y个线程Z个虚拟机你想怎么来就怎么来,一切都根据你的需求来设计即可(实际设计时只需要搞清楚ENV问题即可)

说到这里必须提一下skynet(一种高性能通用服务器框架),skynet就是对Lua虚拟机一种很高级的应用,每次给别人介绍skynet的“微服务”与Lua虚拟机的关系,都要费不少口舌而且说不清楚,原因就是我们大部分人对进程、线程、虚拟机的关系有一些不准确的、先入为主的概念。

Lua所有API的设计,都带有上面的lua_State* L参数,这就用无副作用的方式让Lua成为了一种非常非常非常适合嵌入的语言。无论你的框架是如何复杂,你总能找到一种简单的嵌入Lua的方式而且对框架没什么影响。

以上例子都说的是服务器框架,因为服务器框架一般逻辑架构比较复杂。其实由于多线程和并发难题的存在,未来的客户端逻辑框架也会有复杂化的趋势,例如Actor、ECS等新的架构也会用在客户端,这种情况下Lua的优势也同样会体现出来。

当然,也是基于同样的原因,skynet这种高并发框架很难修改为除Lua以外的其他语言的版本。

如果你恰好熟悉Python语言,那么正好可以对比一下所谓GIL(Python全局锁)的问题,在理解了Lua的设计思路之后,你就大概能猜到为什么从来没有人提Lua的全局锁了,因为这个问题本身就不存在。


大概意思就说到这里吧,可以在评论中继续探讨。至于Lua速度快、小巧等等其他特点,也都是Lua广泛流行的原因的一部分。

感谢这种神奇的小语言。

本文标题:Lua 是怎样一门语言? - 八卦谈
本文地址:www.ttdhp.com/article/28313.html

天天动画片声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
扫码关注我们