我是老吴,一个爱学习的,嵌入式 Linux 驱动工程师。关注我,一起变得更加优秀吧!
哈喽,老吴这几天都在了解 Lua 这门脚本语言,感觉它太适合我这种懒人了,下面记录一下学习心得。
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 的精髓。http://lua-users.org/wiki/Lua 的官方 wiki,绝佳的学习资料,里面除了有 Lua 入门和进阶文章,还有大量示例代码,理论和实践两手抓,是 Lua 进阶的最好选择。
Lua 进阶教程:https://github.com/LewisJEllis/awesome-luaLua 入门后,我们就可以去找一些高质量、认可度比较高的项目来学习了。这个仓库里收集了许多优秀的 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-peripherylua-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/lovelove2d 是为 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 呗。
—— The End ——