Lua語法要點

来源:http://www.cnblogs.com/bughui/archive/2017/08/04/7287129.html
-Advertisement-
Play Games

Lua語言是一門非常小巧精悍的腳本語言,是C/C++天然的好伴侶。這門語言非常的簡單,但是卻有很多語法細節與C語系不同。熟悉C語系語言的同學們剛接觸這門語言的話,可能會因為數組下標從1開始等原因而感到憤怒。這些細節在剛上手的時候全部記下來確實有些困難。湊巧,我也經歷了這麼一個過程。所以在這裡我就把我... ...


本文在我的獨立博客中的鏈接:http://www.bughui.com/2017/04/01/lua-grammar-points/

這篇文章其實是我在四月一號發佈的,由於我重新註冊了一個博客園帳號,所以今天重新發佈。以下為原文內容:

本文所有內容全部都是我在閱讀了《Programming in Lua》這本書之後整理出來的,可以理解本文為一個快速查詢的“手冊”,因此並不適合零基礎的讀者。入門學習的話,還是建議先看看《Programming in Lua》這本書。本文並未包含所有的Lua語法,並不是Lua語法大全。很多高級特性,相信在你用到的時候,以下內容肯定都已經瞭然於心了,不再需要這種入門級的小手冊了。
另外,今天是愚人節!但是我並不想騙你們!以下內容並不是愚人節的禮物,如果踩到坑,恕我無心。

關於Lua語言的一些基本常識

  • Chunk 是一系列語句,Lua 執行的每一塊語句,比如一個文件或者交互模式下的每一行都是一個 Chunk。一個 Chunk 可以是一個語句,也可以是一系列語句的組合,還可以是函數,Chunk可以很大,在 Lua 中幾個 MByte 的 Chunk 是很常見的。
  • 每個語句結尾的分號(;)是可選的,但如果同一行有多個語句最好用;分開
  • 命令lua -la -lb首先在一個 Chunk 內先運行 a 然後運行 b。(註意:-l 選項會調用 require,將會在指定的目錄下搜索文件,如果環境變數沒有設好,上面的命令可能不能正確運行。)
  • lua -i -la -lb,-i 選項要求 Lua 運行指定 Chunk 後進入交互模式.
  • dofile 函數載入文件並執行它
  • 全局變數不需要聲明,給一個變數賦值後即創建了這個全局變數,訪問一個沒有初始化的全局變數也不會出錯,只不過得到的結果是:nil.當且僅當一個變數不等於 nil 時,這個變數存在。
  • Lua 是大小寫敏感的.
  • 單行註釋:-- 註釋內容
  • 多行註釋:--[[ 註釋內容,這裡可以有多行。 --]]
  • 可以直接通過命令參數傳入Lua語句。prompt> lua -e "print(math.sin(12))" --> -0.53657291800043 -e:直接將命令傳入 Lua
  • 全局變數 arg 存放 Lua 的命令行參數。

類型和值

  • Lua 是動態類型語言,變數不要類型定義。 Lua 中有 8 個基本類型分別為: nil、boolean、number、string、userdata、function、thread 和 table。函數 type 可以測試給定變數或者值的類型。
  • 關於布爾值需要註意:Lua 中所有的值都可以作為布爾值來用。在控制結構的條件中除了 false 和 nil 為假,其他值都為真。Lua 認為 0 和空串都是真。
  • 可以使用單引號或者雙引號表示字元串
  • 除了雙引號和單引號,還可以使用[[...]]表示字元串。這種形式的字元串可以包含多行,可以嵌套且不會解釋轉義序列,如果第一個字元是換行符會被自動忽略掉。這種形式的字元串用來包含一段代碼是非常方便的。
  • 運行時,Lua 會自動在 string 和 numbers 之間自動進行類型轉換,當一個字元串使用算術操作符時,string 就會被轉成數字。反過來,當 Lua 期望一個 string 而碰到數字時,會將數字轉成 string。
  • ..在 Lua 中是字元串連接符,當在一個數字後面寫..時,必須加上空格以防止被解釋錯。print(10 .. 20) --> 1020

    表達式和運算符

  • Lua中不等號是~=
  • 如果兩個值類型不同,Lua 認為兩者不同;nil 只和自己相等。Lua 通過引用比較 tables、userdata、functions。也就是說當且僅當兩者表示同一個對象時相等。
  • Lua 比較數字按傳統的數字大小進行,比較字元串按字母的順序進行,但是字母順序依賴於本地環境。
  • Lua的邏輯運算符是 and or not
  • list 風格初始化和 record 風格初始化是[expression]一般初始化的特例
  • Lua數組下標從1開始

    基本語法

  • Lua 可以對多個變數同時賦值,變數列表和值列表的各個元素用逗號分開,賦值語句右邊的值會依次賦給左邊的變數。a,b = 10, 2x <--> a=10; b=2x。多值賦值經常用來交換變數,或將函數調用返回給變數:a, b = f()
  • 遇到賦值語句 Lua 會先計算右邊所有的值然後再執行賦值操作,所以我們可以這樣進行交換變數的值:x, y = y, x。變數個數 > 值的個數 按變數個數補足 nil,變數個數 < 值的個數 多餘的值會被忽略。
  • 使用local 創建一個局部變數,與全局變數不同,局部變數只在被聲明的那個代碼塊內有效。代碼塊:指一個控制結構內,一個函數體,或者一個 chunk(變數被聲明的那個文件或者文本串)。
  • do..end(相當於 c/c++的{})

    流程式控制制語句

    條件

if conditions then
    print("hello elvin!");
end;

if conditions then
    print("hello elvin!");
else
    print("hello elvin!");
end;

if conditions then
    print("hello elvin!");
elseif conditions then
    print("hello elvin!");
    -- 多個elseif
else
    print("hello elvin!");
end

迴圈

while 語句
while condition do
    print("hello elvin!");
end;
repeat-until 語句
repeat
    print("hello elvin!");
until conditions;
for 語句

for 語句有兩大類

第一類,數值for迴圈
for var=exp1,exp2,exp3 do
    loop-part
end

for 將用 exp3 作為 step 從 exp1(初始值)到 exp2(終止值),執行 loop-part。其中exp3可以省略,預設step=1。
有幾點需要註意:

  1. 三個表達式只會被計算一次,並且是在迴圈開始前。

    for i=1,f(x) do
    print(i)
    end
    for i=10,1,-1 do
    print(i)
    end

    第一個例子 f(x)只會在迴圈前被調用一次。

  2. 控制變數 var 是局部變數自動被聲明,並且只在迴圈內有效.

    for i=1,10 do
    print(i)
    end
    max = i
    -- probably wrong! 'i' here is global

    如果需要保留控制變數的值,需要在迴圈中將其保存

    -- find a value in a list
    local found = nil
    for i=1,a.n do
    if a[i] == value then
        found = i
        -- save value of 'i'
        break
    end
    end
    print(found)
  3. 迴圈過程中不要改變控制變數的值,那樣做的結果是不可預知的。
    如果要退出迴圈,使用 break 語句。

第二類,範型for迴圈

前面已經見過一個例子:

-- print all values of array 'a'
for i,v in ipairs(a) do
    print(v)
end

範型 for 遍歷迭代子函數返回的每一個值。再看一個遍歷表 key 的例子:

-- print all keys of table 't'
for k in pairs(t) do
    print(k)
end

範型 for 和數值 for 有兩點相同:

  1. 控制變數是局部變數
  2. 不要修改控制變數的值

再看一個例子,假定有一個表:

days = {"Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"}

現在想把對應的名字轉換成星期幾,一個有效地解決問題的方式是構造一個反向表:

revDays = {
  ["Sunday"] = 1,
  ["Monday"] = 2,
  ["Tuesday"] = 3,
  ["Wednesday"] = 4,
  ["Thursday"] = 5,
  ["Friday"] = 6,
  ["Saturday"] = 7
}

下麵就可以很容易獲取問題的答案了:

x = "Tuesday"
print(revDays[x])
--> 3

其實,我們不需要手工做這件事情,可以自動構造反向表。

revDays = {}
for i,v in ipairs(days) do
    revDays[v] = i
end

Lua 語法要求break和return只能出現在block的結尾一句(也就是說:作為 chunk的最後一句,或者在end之前,或者else前,或者until前),有時候為了調試或者其他目的需要在block的中間使用return或者break,可以顯式的使用do..end來實現:

do return end

函數

  1. 函數定義語法

    function func_name(arguments-list)
    statements-list;
    end;
  2. 調用函數的時候,如果參數列表為空,必須使用()表明是函數調用。上述規則有一個例外,當函數只有一個參數並且這個參數是字元串或者表構造的時候,()可有可無:

    print "Hello World" -- -> print("Hello World")
    dofile 'a.lua' -- -> dofile ('a.lua')
    f{x=10, y=20} -- -> f({x=10, y=20})
    type{} -- -> type({})
  3. Lua 函數實參和形參的匹配與賦值語句類似,多餘部分被忽略,缺少部分用 nil 補足。

  4. Lua 函數可以接受可變數目的參數,和 C 語言類似在函數參數列表中使用三點(...)表示函數有可變的參數。Lua 將函數的參數放在一個叫 arg 的表中,除了參數以外,arg表中還有一個域 n 表示參數的個數。

  5. 如果我們只想要 string.find 返回的第二個值。一個典型的方法是使用啞元(dummy variable,下劃線):

    local _, x = string.find(s, p)
  6. 使用圓括弧強制使調用返回一個值。

    print((foo0()))
    -- 將只列印foo0的第一個返回值。
  7. Lua中定義方法的另一種特殊方式

    Lib = {}
    function Lib.foo (x,y)
    return x + y
    end
  8. 當我們將函數保存在一個局部變數內時,我們得到一個局部函數,也就是說局部函數像局部變數一樣在一定範圍內有效。
    • 方式一
    local f = function (...)
    
    end
    local g = function (...)
        f()
        -- external local `f' is visible here
    end
    • 方式二
    local function f (...)
    
    end
  9. 在定義非直接遞歸局部函數時要先聲明然後定義才可以

環境

Lua 用一個名為 environment 普通的表來保存所有的全局變數。
Lua 將環境本身存儲在一個全局變數_G 中,(_G._G 等於_G)。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 操作系統 : CentOS7.3.1611_x64 python版本:2.7.5 sklearn版本:0.18.2 tensorflow版本 :1.2.1 多項式的定義及展現形式 多項式(Polynomial)是代數學中的基礎概念,是由稱為不定元的變數和稱為繫數的常數通過有限次加減法、乘法以及自然數 ...
  • 平行運算 前言: 編寫Python程式時,我們可能會遭遇性能問題,即使優化了代碼,程式也依然有可能運行的很慢,從而無法滿足我們對執行速度的要求,目前的電腦,其cpu核心數越來越多,於是,我們可以考慮通過平行計算來提升性能,能不能把代碼的總計算量分配到多個獨立的任務之中,併在多個CPU核心上面同時運 ...
  • 一、apache、php、mysql安裝 1.安裝php 分步式安裝: 下載php:wget http://cn2.php.NET/get/php-7.0.11.tar.gz/from/this/mirror 解壓:tar -zxvf mirror 安裝gcc:yum install -y gcc ...
  • 1、break break是終止本次迴圈,比如你很多個while迴圈,你在其中一個while迴圈里寫了一個break,滿足條件,只會終止這個while裡面的迴圈,程式會跳到上一層while迴圈繼續往下走 以簡單的for迴圈來舉例 ...
  • from flask import Flask,make_response,jsonify,request,url_for,g from flask_restful import reqparse, abort, Api, Resource from flask_httpauth import HT... ...
  • Java 記憶體區域和GC機制 目錄 Java垃圾回收概況 Java記憶體區域 Java對象的訪問方式 Java記憶體分配機制 Java GC機制 垃圾收集器 Java垃圾回收概況 Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為J ...
  • 總結:本篇博客介紹使用gregwar/captcha實現驗證碼的具體操作步驟,以及可能遇到的問題和解決辦法。 操作步驟: 1, 在laravel5.4項目根目錄下找到 composer.json 這個文件, 添加 "gregwar/captcha": "1.*" 到composer.json這個文件 ...
  • 簡單的寫了一個爬取www.seebug.org上poc的小玩意兒~ 首先我們進行一定的抓包分析 我們遇到的第一個問題就是seebug需要登錄才能進行下載,這個很好處理,只需要抓取返回值200的頁面,將我們的headers信息複製下來就行了 (這裡我就不放上我的headers信息了,不過headers ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...