Skip to content

基本語法

變數定義

  • 變數在使用前,需要在程式碼中進行宣告,即建立該變數。
  • 編譯程式執行程式碼之前編譯器需要知道如何給語句變數開闢儲存區,用於儲存變數的值。
  • Lua 變數有三種類型:全域性變數、區域性變數、表中的域。
  • Lua 中的變數全是全域性變數,哪怕是語句塊或是函數里,除非用 local 顯式宣告為區域性變數。
  • 區域性變數的作用域為從宣告位置開始到所在語句塊結束。
  • 變數的預設值均為 nil。
lua
-- test.lua 文件脚本
a = 5               -- 全局变量
local b = 5         -- 局部变量

function joke()
    c = 5           -- 全局变量
    local d = 6     -- 局部变量
end

joke()
print(c,d)          --> 5 nil

do 
    local a = 6     -- 局部变量
    b = 6           -- 对局部变量重新赋值
    print(a,b);     --> 6 6
end

print(a,b)      --> 5 6

輸出結果為:

lua
5    nil
6    6
5    6

資料型別

  • Lua是動態型別語言,變數不要型別定義,只需要為變數賦值。
  • 值可以儲存在變數中,作為引數傳遞或結果返回。
  • Lua中有8個基本型別,AIV只使用其中5種,分別為:nil、boolean、number、stringfunction。
資料型別描述
nil只有值nil屬於該類,表示一個無效值(在條件表示式中相當於false)。
boolean包含兩個值:false和true。
number表示雙精度型別的實浮點數
string字串由一對雙引號或單引號來表示
function由C或Lua編寫的函式
lua
print(type("Hello world"))      --> string
print(type(10.4*3))             --> number
print(type(print))              --> function
print(type(type))               --> function
print(type(true))               --> boolean
print(type(nil))                --> nil
print(type(type(X)))            --> string

流程控制

  • Lua 程式語言流程控制語句通過程式設定一個或多個條件語句來設定。在條件為 true 時執行指定程式程式碼,在條件為 false 時執行其他指定程式碼。

if語句

lua
--[ 0 为 true ]
if(0)
then
    print("0 为 true")
end

輸出結果為:

lua
0true

if...else語句

lua
if(布尔表达式)
then
   --[ 布尔表达式为 true 时执行该语句块 --]
else
   --[ 布尔表达式为 false 时执行该语句块 --]
end

以下用於判斷變數a的值:

lua
--[ 定义变量 --]
a = 100;
--[ 检查条件 --]
if( a < 20 )
then
   --[ if 条件为 true 时执行该语句块 --]
   print("a 小于 20" )
else
   --[ if 条件为 false 时执行该语句块 --]
   print("a 大于 20" )
end
print("a 的值为 :", a)

輸出結果為:

lua
a 大于 20
a 的值为 :    100

if...elseif...else 語句

lua
if( 布尔表达式 1)
then
   --[ 在布尔表达式 1 为 true 时执行该语句块 --]

elseif( 布尔表达式 2)
then
   --[ 在布尔表达式 2 为 true 时执行该语句块 --]

elseif( 布尔表达式 3)
then
   --[ 在布尔表达式 3 为 true 时执行该语句块 --]
else 
   --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]
end

以下用於判斷變數a的值:

lua
--[ 定义变量 --]
a = 100

--[ 检查布尔条件 --]
if( a == 10 )
then
   --[ 如果条件为 true 打印以下信息 --]
   print("a 的值为 10" )
elseif( a == 20 )
then   
   --[ if else if 条件为 true 时打印以下信息 --]
   print("a 的值为 20" )
elseif( a == 30 )
then
   --[ if else if condition 条件为 true 时打印以下信息 --]
   print("a 的值为 30" )
else
   --[ 以上条件语句没有一个为 true 时打印以下信息 --]
   print("没有匹配 a 的值" )
end
print("a 的真实值为: ", a )

輸出結果為:

lua
没有匹配 a 的值
a 的真实值为:     100

if巢狀

可以在一個if或elseif語句中插入其他的if或elseif語句。語法如下:

lua
if( 布尔表达式 1)
then
   --[ 布尔表达式 1 为 true 时执行该语句块 --]
   if(布尔表达式 2)
   then
      --[ 布尔表达式 2 为 true 时执行该语句块 --]
   end
end
lua
--[ 定义变量 --]
a = 100;
b = 200;

--[ 检查条件 --]
if( a == 100 )
then
   --[ if 条件为 true 时执行以下 if 条件判断 --]
   if( b == 200 )
   then
      --[ if 条件为 true 时执行该语句块 --]
      print("a 的值为 100 b 的值为 200" );
   end
end
print("a 的值为 :", a );
print("b 的值为 :", b );

輸出結果為:

lua
a 的值为 100 b 的值为 200
a 的值为 :    100
b 的值为 :    200

迴圈控制

for迴圈

  • for迴圈語句可以重複執行指定語句,重複次數可在for語句中控制。
  • for語句有兩大類:數值for迴圈、泛型for迴圈

數值for迴圈

lua
for var=exp1,exp2,exp3 do  
    <执行体>  
end

var 從 exp1 變化到 exp2,每次變化以 exp3 為步長遞增 var,並執行一次 "執行體"。exp3 是可選的,如果不指定,預設為1。

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

for的三個表示式在迴圈開始前一次性求值,以後不再進行求值。比如上面的f(x)只會在迴圈開始前執行一次,其結果用在後面的迴圈中。舉例如下:

lua
function f(x)  
    print("function")  
    return x*2   
end  
for i=1,f(5) do print(i)  
end

輸出結果為:

lua
function
1
2
3
4
5
6
7
8
9
10

泛型for迴圈

泛型for迴圈通過一個迭代器函式來遍歷所有值,類似java中的foreach語句。

lua
--打印数组a的所有值  
a = {"one", "two", "three"}
for i, v in ipairs(a) do
    print(i, v)
end

i是陣列索引值,v是對應索引的陣列元素值。ipairs是Lua提供的一個迭代器函式,用來迭代陣列。舉例如下:

lua
#!/usr/local/bin/lua  
days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}  
for i,v in ipairs(days) do  print(v) end

輸出結果為:

lua
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

while迴圈

  • while 迴圈語句在判斷條件為 true 時會重複執行迴圈體語句。語法為:
lua
while(condition)
do
   statements
end

在condition(條件)為 false 時會跳過當前迴圈並開始指令碼執行緊接著的語句。舉例如下:

lua
a=10
while( a < 20 )
do
   print("a 的值为:", a)
   a = a+1
end

輸出結果為:

lua
a 的值为:    10
a 的值为:    11
a 的值为:    12
a 的值为:    13
a 的值为:    14
a 的值为:    15
a 的值为:    16
a 的值为:    17
a 的值为:    18
a 的值为:    19

函式

  • 函式是對語句和表示式進行抽象的主要方法。既可以用來處理一些特殊的工作,也可以用來計算一些值。
  • 函式主要有兩種用途:
  1. 完成指定的任務,這種情況下函式作為呼叫語句使用;
  2. 計算並返回值,這種情況下函式作為賦值語句的表示式使用。

函式定義

lua
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
    function_body
    return result_params_comma_separated
end
  • optional_function_scope: 該引數是可選的指定函式是全域性函式還是區域性函式,未設定該引數預設為全域性函式,如果你需要設定函式為區域性函式需要使用關鍵字 local。
  • function_name: 指定函式名稱。
  • argument1, argument2, argument3..., argumentn: 函式引數,多個引數以逗號隔開,函式也可以不帶引數。
  • function_body: 函式體,函式中需要執行的程式碼語句塊。
  • result_params_comma_separated: 函式返回值,Lua語言函式可以返回多個值,每個值以逗號隔開。
lua
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result; 
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))

上面例項定義了函式 max(),引數為 num1, num2,用於比較兩值的大小,並返回最大值,輸出結果為:

lua
两值比较最大值为     10
两值比较最大值为     6

多返回值

  • 函式可以返回多個結果值,比如string.find,其返回匹配串"開始和結束的下標"(如果不存在匹配串返回nil)
lua
function maximum (a)
    local mi = 1             -- 最大值索引
    local m = a[mi]          -- 最大值
    for i,val in ipairs(a) do
       if val > m then
           mi = i
           m = val
       end
    end
    return m, mi
end

print(maximum({8,10,23,12,5}))

上例表示,在return後列出要返回的值的列表即可返回多值,輸出結果為:

lua
23    3

運算子

運算子是一個特殊的符號,用於告訴直譯器執行特定的數學或邏輯運算。Lua提供了以下幾種運算子型別:

  • 算術運算子
  • 關係運算符
  • 邏輯運算子
  • 其他運算子

算術運算子

設定 A 的值為10,B 的值為 20:

運算子描述例項
+加法A + B 輸出結果 30
-減法A - B 輸出結果 -10
*乘法A * B 輸出結果 200
/除法B / A 輸出結果 2
%取餘B % A 輸出結果 0
^乘冪A^2 輸出結果 100
-負號-A 輸出結果 -10
//整除運算子5//2 輸出結果 2

關係運算符

設定 A 的值為10,B 的值為 20:

運算子描述例項
==等於,檢測兩個值是否相等,相等返回 true,否則返回 false(A == B) 為 false
~=不等於,檢測兩個值是否相等,不相等返回 true,否則返回 false(A ~= B) 為 true
>大於,如果左邊的值大於右邊的值,返回 true,否則返回 false(A > B) 為 false
<小於,如果左邊的值小於右邊的值,返回 true,否則返回 false(A < B) 為 true
>=大於等於,如果左邊的值大於等於右邊的值,返回 true,否則返回 false(A >= B) 返回 false
<=小於等於,如果左邊的值小於等於右邊的值,返回 true,否則返回 false(A <= B) 返回 false

邏輯運算子

設定 A 的值為 true,B 的值為 false:

運算子描述例項
and邏輯與運算子。 若 A 為 false,則返回 A,否則返回 B(A and B) 為 false
or邏輯或運算子。 若 A 為 true,則返回 A,否則返回 B(A or B) 為 true
not邏輯非運算子。與邏輯運算結果相反,如果條件為 true,邏輯非為 falsenot(A and B) 為 true

其他運算子

下表列出了連線運算子與計算表或字串長度的運算子:

運算子描述例項
..連線兩個字串a..b ,其中 a 為 "Hello " , b 為 "AI-Vision", 輸出結果為 "Hello AI-Vision"
#獲取字串長度#"Hello" 返回 5

運算子優先順序

從高到低的順序:

lua
^
not    - (unary)
*      /       %
+      -
..
<      >      <=     >=     ~=     ==
and
or

除了 ^ 和 .. 外所有的二元運算子都是左連線的。

lua
a+i < b/2+1          <-->       (a+i) < ((b/2)+1)
5+x^2*8              <-->       5+((x^2)*8)
a < y and y <= z     <-->       (a < y) and (y <= z)
-x^2                 <-->       -(x^2)
x^y^z                <-->       x^(y^z)

舉例如下:

lua
a = 20
b = 10
c = 15
d = 5

e = (a + b) * c / d;-- ( 30 * 15 ) / 5
print("(a + b) * c / d 运算值为  :",e )

e = ((a + b) * c) / d; -- (30 * 15 ) / 5
print("((a + b) * c) / d 运算值为 :",e )

e = (a + b) * (c / d);-- (30) * (15/5)
print("(a + b) * (c / d) 运算值为 :",e )

e = a + (b * c) / d;  -- 20 + (150/5)
print("a + (b * c) / d 运算值为   :",e )

輸出結果為:

lua
(a + b) * c / d 运算值为  :    90.0
((a + b) * c) / d 运算值为 :    90.0
(a + b) * (c / d) 运算值为 :    90.0
a + (b * c) / d 运算值为   :    50.0

字串

字串或串(String)是由數字、字母、下劃線組成的一串字元。
字串是一種基本的資料型別,用於儲存文本資料。
字串可以包含任意字元,包括字母、數字、符號、空格以及其他特殊字元。
符串可以使用以下三種方式來表示:

  • 單引號間的一串字元
lua
local str1 = 'This is a string.'
local str2 = "This is also a string."
  • 雙引號間的一串字元
lua
local str = "Hello, "
str = str .. "World!"  -- 创建一个新的字符串并将其赋值给str
print(str)  -- 输出 "Hello, World!"
  • [[ 與 ]] 間的一串字元
lua
local multilineString = [[
This is a multiline string.
It can contain multiple lines of text.
No need for escape characters.
]]

print(multilineString)

以上三種方式的字串舉例如下:

lua
string1 = "Hello"
print("\"字符串 1 是\"",string1)
string2 = 'AI-Vision'
print("字符串 2 是",string2)

string3 = [["Hello AI-Vision"]]
print("字符串 3 是",string3)

輸出結果為:

lua
"字符串 1 是"    Hello
字符串 2 是    AI-Vision
字符串 3 是    "Hello AI-Vision"

字串長度計算

要計算字串的長度(即字串中字元的個數),可以使用 string.len函式或 utf8.len 函式,包含中文的一般用 utf8.len,string.len 函式用於計算只包含 ASCII 字串的長度。舉例如下:

lua
local myString = "Hello, 世界!"

-- 计算字符串的长度(字符个数)
local length1 = utf8.len(myString)
print(length1) -- 输出 9

-- string.len 函数会导致结果不准确
local length2 = string.len(myString)
print(length2) -- 输出 14

跳脫字元

跳脫字元用於表示不能直接顯示的字元,比如後退鍵,回車鍵等,如在字串轉換雙引號可以使用 \。
所有的跳脫字元和所對應的意義:

跳脫字元意義ASCII碼值(十進位制)
\a響鈴(BEL)007
\b退格(BS) ,將當前位置移到前一列008
\f換頁(FF),將當前位置移到下頁開頭012
\n換行(LF) ,將當前位置移到下一行開頭010
\r回車(CR) ,將當前位置移到本行開頭013
\t水平製表(HT) (跳到下一個TAB位置)009
\v垂直製表(VT)011
\代表一個反斜線字元'''092
'代表一個單引號(撇號)字元039
"代表一個雙引號字元034
\0空字元(NULL)000
\ddd1到3位八進位制數所代表的任意字元三位八進位制
\xhh1到2位十六進位制所代表的任意字元二位十六進位制

字串操作

常用字串操作

序號方法 & 用途
1string.upper(argument):
字串全部轉為大寫字母。
2string.lower(argument):
字串全部轉為小寫字母。
3string.sub(s, i [, j]):
s 為要擷取的字串,i 為擷取開始位置,j 為擷取結束位置,預設為 -1,最後一個字元。
4string.gsub(mainString,findString,replaceString,num)
在字串中替換。
mainString 為要操作的字串, findString 為被替換的字元,replaceString 要替換的字元,num 替換次數(可以忽略,則全部替換),如:
string.gsub("aaaa","a","z",3);
zzza    3
5string.find (str, substr, [init, [plain]])
在一個指定的目標字串 str 中搜索指定的內容 substr,如果找到了一個匹配的子串,就會返回這個子串的起始索引和結束索引,不存在則返回 nil。
init 指定了搜尋的起始位置,預設為 1,可以一個負數,表示從後往前數的字元個數。
plain 表示是否使用簡單模式,預設為 false,true 只做簡單的查詢子串的操作,false 表示使用使用正則模式匹配。
以下例項查詢字串 "Lua" 的起始索引和結束索引位置:
string.find("Hello Lua user", "Lua", 1)
7 9
6string.reverse(arg)
字串反轉
string.reverse("Lua")
auL
7string.format(...)
返回一個類似printf的格式化字串
string.format("the value is:%d",4)
the value is:4
8string.char(arg) 和 string.byte(arg[,int])
char 將整型數字轉成字元並連線, byte 轉換字元為整數值(可以指定某個字元,預設第一個字元)
string.char(97,98,99,100)
abcd
string.byte("ABCD",4)
68
string.byte("ABCD")
65
9string.len(arg)
計算字串長度
string.len("abc")
3
10string.rep(string, n)
返回字串string的n個複製
string.rep("abcd",2)
abcdabcd
11..
連結兩個字串
print("www.ai-v".."ision.com")
www.ai-vision.com
12string.gmatch(str, pattern)
返回一個迭代器函式,每一次呼叫這個函式,返回一個在字串 str 找到的下一個符合 pattern 描述的子串。如果引數 pattern 描述的字串沒有找到,迭代函式返回nil
for word in string.gmatch("Hello ai vision", "%a+") do print(word) end
Hello
ai
vision
13string.match(str, pattern, init)
string.match()只尋找源字串str中的第一個配對. 引數init可選, 指定搜尋過程的起點, 預設為1。
在成功配對時, 函式將返回配對錶達式中的所有捕獲結果; 如果沒有設定捕獲標記, 則返回整個配對字串. 當沒有成功的配對時, 返回nil
string.match("I have 2 questions for you.", "%d+ %a+")
2 questions
string.format("%d, %q", string.match("I have 2 questions for you.", "(%d+) (%a+)"))
2, "questions"

字串格式化

string.format() 函式來生成具有特定格式的字串, 函式的第一個引數是格式 , 之後是對應格式中每個代號的各種資料。
由於格式字串的存在, 使得產生的長字串可讀性大大提高了。這個函式的格式很像 C 語言中的 printf()。
以下例項演示瞭如何對字串進行格式化操作:
格式字串可能包含以下的轉義碼:

  • %c - 接受一個數字, 並將其轉化為ASCII碼錶中對應的字元
  • %d, %i - 接受一個數字並將其轉化為有符號的整數格式
  • %o - 接受一個數字並將其轉化為八進位制數格式
  • %u - 接受一個數字並將其轉化為無符號整數格式
  • %x - 接受一個數字並將其轉化為十六進位制數格式, 使用小寫字母
  • %X - 接受一個數字並將其轉化為十六進位制數格式, 使用大寫字母
  • %e - 接受一個數字並將其轉化為科學記數法格式, 使用小寫字母e
  • %E - 接受一個數字並將其轉化為科學記數法格式, 使用大寫字母E
  • %f - 接受一個數字並將其轉化為浮點數格式
  • %g(%G) - 接受一個數字並將其轉化為%e(%E, 對應%G)及%f中較短的一種格式
  • %q - 接受一個字串並將其轉化為可安全被Lua編譯器讀入的格式
  • %s - 接受一個字串並按照給定的引數格式化該字串

為進一步細化格式, 可以在%號後新增引數. 引數將以如下的順序讀入:

  1. 符號: 一個+號表示其後的數字轉義符將讓正數顯示正號. 預設情況下只有負數顯示符號.
  2. 佔位符: 一個0, 在後面指定了字串寬度時佔位用. 不填時的預設佔位符是空格.
  3. 對齊標識: 在指定了字串寬度時, 預設為右對齊, 增加-號可以改為左對齊.
  4. 寬度數值
  5. 小數位數/字串裁切: 在寬度數值後增加的小數部分n, 若後接f(浮點數轉義符, 如%6.3f)則設定該浮點數的小數只保留n位, 若後接s(字串轉義符, 如%5.3s)則設定該字串只顯示前n位.
lua
string1 = "Hello"
string2 = "Ai-Vision"
number1 = 10
number2 = 20
-- 基本字符串格式化
print(string.format("基本格式化 %s %s",string1,string2))
-- 日期格式化
date = 2; month = 1; year = 2023
print(string.format("日期格式化 %02d/%02d/%03d", date, month, year))
-- 十进制格式化
print(string.format("%.4f",1/3))

輸出結果為:

lua
基本格式化 Hello Ai-Vision
日期格式化 02/01/2023
0.3333

其他例子:

lua
string.format("%c", 83)                 -- 输出S
string.format("%+d", 17.0)              -- 输出+17
string.format("%05d", 17)               -- 输出00017
string.format("%o", 17)                 -- 输出21
string.format("%u", 3.14)               -- 输出3
string.format("%x", 13)                 -- 输出d
string.format("%X", 13)                 -- 输出D
string.format("%e", 1000)               -- 输出1.000000e+03
string.format("%E", 1000)               -- 输出1.000000E+03
string.format("%6.3f", 13)              -- 输出13.000
string.format("%q", "One\nTwo")         -- 输出"One\
                                        --   Two"
string.format("%s", "monkey")           -- 输出monkey
string.format("%10s", "monkey")         -- 输出    monkey
string.format("%5.3s", "monkey")        -- 输出  mon

字串擷取

lua
-- 字符串
local sourcestr = "prefix--abcdefgh--suffix"
print("\n原始字符串", string.format("%q", sourcestr))

-- 截取部分,第4个到第15个
local first_sub = string.sub(sourcestr, 4, 15)
print("\n第一次截取", string.format("%q", first_sub))

-- 取字符串前缀,第1个到第8个
local second_sub = string.sub(sourcestr, 1, 8)
print("\n第二次截取", string.format("%q", second_sub))

-- 截取最后10个
local third_sub = string.sub(sourcestr, -10)
print("\n第三次截取", string.format("%q", third_sub))

-- 索引越界,输出原始字符串
local fourth_sub = string.sub(sourcestr, -100)
print("\n第四次截取", string.format("%q", fourth_sub))

輸出結果為:

lua
原始字符串    "prefix--abcdefgh--suffix"

第一次截取    "fix--abcdefg"

第二次截取    "prefix--"

第三次截取    "gh--suffix"

第四次截取    "prefix--abcdefgh--suffix"

陣列

陣列,就是相同資料型別的元素按一定順序排列的集合,可以是一維陣列和多維陣列。
在 Lua 中,陣列不是一種特定的資料型別,而是一種用來儲存一組值的資料結構。
實際上,Lua 中並沒有專門的陣列型別,而是使用一種被稱為 "table" 的資料結構來實現陣列的功能。

一維陣列

一維陣列是最簡單的陣列,其邏輯結構是線性表。
使用索引訪問陣列元素

lua
-- 创建一个数组
local myArray = {10, 20, 30, 40, 50}

-- 访问数组元素
print(myArray[1])  -- 输出 10
print(myArray[3])  -- 输出 30

要計算陣列的長度(即陣列中元素的個數),可以使用 # 運算子:

lua
local myArray = {10, 20, 30, 40, 50}

-- 计算数组长度
local length = #myArray

print(length) -- 输出 5

一維陣列可以用 for 迴圈出陣列中的元素,如下例項:

lua
-- 创建一个数组
local myArray = {10, 20, 30, 40, 50}

-- 循环遍历数组
for i = 1, #myArray do
    print(myArray[i])
end

輸出結果為:

lua
10
20
30
40
50

Vision Studio