我是老吳,一個(gè)愛(ài)學(xué)習(xí)的,嵌入式 Linux 驅(qū)動(dòng)工程師。關(guān)注我,一起變得更加優(yōu)秀吧!
哈嘍,老吳這幾天都在了解 Lua 這門(mén)腳本語(yǔ)言,感覺(jué)它太適合我這種懶人了,下面記錄一下學(xué)習(xí)心得。
Lua 是什么?
Lua 是一門(mén)腳本語(yǔ)言,和 Shell、Python 是同一種類(lèi)型。
https://www.lua.org/about.html
Lua 的優(yōu)點(diǎn)很多,下面是我感受比較深的幾點(diǎn):
文檔:Lua 官方提供了非常豐富的文檔。經(jīng)過(guò)我這幾天的了解,我甚至覺(jué)得 Lua 很適合作為學(xué)習(xí)編程的第一門(mén)語(yǔ)言。
小巧:Lua 是 C語(yǔ)言寫(xiě)的,5.4.4版本大約 3 萬(wàn)行代碼,編譯后算上標(biāo)準(zhǔn)庫(kù)才 281K,對(duì)嵌入式平臺(tái)很友好。
簡(jiǎn)潔:Lua 的語(yǔ)法簡(jiǎn)單明了,自由度高。有經(jīng)驗(yàn)的 C 語(yǔ)言開(kāi)發(fā)者大概 1 天就可以用 Lua 寫(xiě)程序了。
高效:相對(duì)于其他腳本語(yǔ)言而言,as fast as Lua。易移植:無(wú)依賴(lài),在 PC / 嵌入式 、Windows / Unix 平臺(tái)上都很容易編譯,在我的筆記本上幾秒鐘就編譯完了。
強(qiáng)大:支持過(guò)程式編程、面向?qū)ο缶幊?、函?shù)式編程、數(shù)據(jù)驅(qū)動(dòng)編程。
Lua 設(shè)計(jì)中的一個(gè)基本概念是為實(shí)現(xiàn)特性提供元機(jī)制,而不是直接在語(yǔ)言中提供大量特性。例如,雖然 Lua 不是純粹的面向?qū)ο笳Z(yǔ)言,但它提供了用于實(shí)現(xiàn)類(lèi)和繼承的元機(jī)制。和其他類(lèi)似的語(yǔ)言進(jìn)行比較:
Lua 怎么學(xué)?
下面我感覺(jué)比較好的學(xué)習(xí)資料,按照我學(xué)習(xí)的先后順序進(jìn)行排列。Lua 快速入門(mén):https://github.com/PacktPublishing/Lua-Quick-Start-Guide這是《Lua Quick Start Guide》一書(shū)的配套源碼。
這本書(shū)比較淺現(xiàn)易懂,適合快速體驗(yàn) Lua 這門(mén)語(yǔ)言。我快速地瀏覽了一遍書(shū)的大體內(nèi)容,然后直接看源碼,遇到不懂的地方再回頭看書(shū)。比較難的地方是第三章末尾的 metatable 相關(guān)的內(nèi)容,metatable 可能是 Lua 的精髓。http://lua-users.org/wiki/Lua 的官方 wiki,絕佳的學(xué)習(xí)資料,里面除了有 Lua 入門(mén)和進(jìn)階文章,還有大量示例代碼,理論和實(shí)踐兩手抓,是 Lua 進(jìn)階的最好選擇。
Lua 進(jìn)階教程:https://github.com/LewisJEllis/awesome-luaLua 入門(mén)后,我們就可以去找一些高質(zhì)量、認(rèn)可度比較高的項(xiàng)目來(lái)學(xué)習(xí)了。這個(gè)倉(cāng)庫(kù)里收集了許多優(yōu)秀的 Lua 開(kāi)源項(xiàng)目,找?guī)讉€(gè)自己感興趣的項(xiàng)目,研讀其代碼并不斷地編碼,足夠讓我們成為一個(gè)合格的 Lua 開(kāi)發(fā)者了。
Lua 怎么用?
為了更好地感受 Lua 這門(mén)語(yǔ)言的用法,下面會(huì)舉 4 個(gè)不同場(chǎng)景的例子。示例1:文件讀寫(xiě)
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()
上面的代碼演示了最簡(jiǎn)單的文件讀寫(xiě)。
示例2:控制硬件https://github.com/vsergeev/lua-peripherylua-periphery 是一個(gè)庫(kù),用于在 Linux 的用戶(hù)空間中訪(fǎng)問(wèn) 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 語(yǔ)言編寫(xiě)的,除了標(biāo)準(zhǔn)庫(kù)之外,還有大量的第三方庫(kù)。lua-periphery 60%的代碼是 C,C 負(fù)責(zé)硬件的訪(fǎng)問(wèn)。另外的 40% 的示例代碼是 Lua 寫(xiě)的。如果你想了解如何用 C 來(lái)擴(kuò)展 Lua,看這個(gè)開(kāi)源項(xiàng)目就夠了。
示例3:網(wǎng)絡(luò)服務(wù)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()
上面的代碼演示了如何用網(wǎng)絡(luò)庫(kù) copas 搭建一個(gè) TCP echo server。
示例4:游戲開(kāi)發(fā)https://github.com/love2d/lovelove2d 是為 Lua 而寫(xiě)的 2D 游戲引擎,市面上有不少商業(yè) 2D 游戲是基于 love2d 開(kāi)發(fā)的。
我們簡(jiǎn)單看下 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
上面的代碼實(shí)現(xiàn)了通過(guò)方向鍵控制瑪麗奧的功能,基于這個(gè)框架,最終我們可以很輕松地實(shí)現(xiàn)超級(jí)瑪麗的核心功能,效果如下:
總結(jié)
Lua 具有小巧、簡(jiǎn)潔、高效、強(qiáng)大、文檔豐富等優(yōu)點(diǎn),如同一把瑞士軍刀,非常適合嵌入式 Linux 平臺(tái)的底層開(kāi)發(fā),是嵌入式開(kāi)發(fā)的利器。人生苦短,一起試下用 Lua 唄。
—— The End ——