作者:老吴嵌入式
链接:https://www.zhihu.com/question/19841006/answer/2491808963
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Lua 是什么?
Lua 是一门脚本语言,和 Shell、Python 是同一种类型。
https://www.lua.org/about.html
Lua 的优点很多,下面是我感受比较深的几点。
文档:
Lua 官方提供了非常丰富的文档。经过我这几天的了解,我甚至觉得 Lua 很适合作为学习编程的第一门语言。
小巧:
Lua 是 C语言写的,5.4.4版本大约 3 万行代码,编译后算上标准库才 281K,对嵌入式平台很友好。
简洁:
Lua 的语法简单明了,自由度高。有经验的 C 语言开发者大概 1 天就可以用 Lua 写程序了。
高效:
相对于其他脚本语言而言,as fast as Lua。
易移植:
无依赖,在 PC / 嵌入式 、Windows / Unix 平台上都很容易编译,在我的笔记本上几秒钟就编译完了。
强大:
支持过程式编程、面向对象编程、函数式编程、数据驱动编程。
Lua 设计中的一个基本概念是为实现特性提供元机制,而不是直接在语言中提供大量特性。
例如,虽然 Lua 不是纯粹的面向对象语言,但它提供了用于实现类和继承的元机制。
和其他类似的语言进行比较:
Lua 怎么学?
下面我感觉比较好的学习资料,按照我学习的先后顺序进行排列。
Lua 快速入门:
https://github.com/PacktPublishing/Lua-Quick-Start-Guide
这是《Lua Quick Start Guide》一书的配套源码。这本书比较浅现易懂,适合快速体验 Lua 这门语言。
我快速地浏览了一遍书的大体内容,然后直接看源码,遇到不懂的地方再回头看书。
比较难的地方是第三章末尾的 metatable 相关的内容,metatable 可能是 Lua 的精髓。
Lua 的官方 wiki,绝佳的学习资料,里面除了有 Lua 入门和进阶文章,还有大量示例代码,理论和实践两手抓,是 Lua 进阶的最好选择。
Lua 进阶教程:
https://github.com/LewisJEllis/awesome-lua
Lua 入门后,我们就可以去找一些高质量、认可度比较高的项目来学习了。
这个仓库里收集了许多优秀的 Lua 开源项目,找几个自己感兴趣的项目,研读其代码并不断地编码,足够让我们成为一个合格的 Lua 开发者了。
Lua 怎么用?
为了更好地感受 Lua 这门语言的用法,下面会举 4 个不同场景的例子。
示例1:文件读写
function SaveCharacterData(name, power, team)
file = io.open("data.txt", "w")
file:write("name " .. name .. "\n")
file:write("attack ", power, "\n")
file:write("team " .. team, "\n")
file:close()
end
-- Write data
SaveCharacterData("gwen", 20, "blue")
-- Read data
file = io.open("data.txt")
lines = file:lines()
print("Contents of file:");
for line in lines do
print("\t" .. line)
end
file:close()
上面的代码演示了最简单的文件读写。
示例2:控制硬件
https://github.com/vsergeev/lua-periphery
lua-periphery 是一个库,用于在 Linux 的用户空间中访问 GPIO、LED、PWM、SPI、I2C、MMIO 等接口。
local GPIO = require('periphery').GPIO
-- Open GPIO /dev/gpiochip0 line 10 with input direction
local gpio_in = GPIO("/dev/gpiochip0", 10, "in")
-- Open GPIO /dev/gpiochip0 line 12 with output direction
local gpio_out = GPIO("/dev/gpiochip0", 12, "out")
local value = gpio_in:read()
gpio_out:write(not value)
gpio_in:close()
gpio_out:close()
Lua 是 C 语言编写的,除了标准库之外,还有大量的第三方库。
lua-periphery 60%的代码是 C,C 负责硬件的访问。
另外的 40% 的示例代码是 Lua 写的。如果你想了解如何用 C 来扩展 Lua,看这个开源项目就够了。
示例3:网络服务
https://github.com/lunarmodules/copas
local copas = require("copas")
local socket = require("socket")
local function echoHandler(skt)
skt = copas.wrap(skt)
while true do
local data = skt:receive()
if not data or data == "quit" then
break
end
skt:send(data)
end
end
local server = socket.bind("localhost", 20000)
copas.addserver(server, echoHandler)copas.loop()
上面的代码演示了如何用网络库 copas 搭建一个 TCP echo server。
示例4:游戏开发
https://github.com/love2d/love
love2d 是为 Lua 而写的 2D 游戏引擎,市面上有不少商业 2D 游戏是基于 love2d 开发的。
点击查看大图
我们简单看下 love2d 的用法。
-- function called at start of game to load assets
function love.load()
love.graphics.setDefaultFilter('nearest', 'nearest')
sprite = love.graphics.newImage('graphics/mario.png')
x = virtualWidth / 2 - sprite:getWidth() / 2
y = virtualHeight / 2 - sprite:getHeight() / 2
push:setupScreen(virtualWidth, virtualHeight, 640, 480, {
fullscreen = false
})
end
-- function called every frame with the delta (dt) since last frame
function love.update(dt)
end
-- a callback function called whenever we press a key
function love.keypressed(key)
if key == 'left' then
x = x - speed
end
if key == 'right' then
x = x + speed
end
[...]
end
-- a function called each frame meant to render things to the screen
function love.draw()
push:apply('start')
love.graphics.draw(sprite, x, y)
push:apply('end')
end
上面的代码实现了通过方向键控制玛丽奥的功能,基于这个框架,最终我们可以很轻松地实现超级玛丽的核心功能,效果如下:
点击查看大图
总结
Lua 具有小巧、简洁、高效、强大、文档丰富等优点,如同一把瑞士军刀,非常适合嵌入式 Linux 平台的底层开发,是嵌入式开发的利器。
人生苦短,一起试下用 Lua 呗。