Lua:簡單入門


  首先,感謝 runoob.com:http://www.runoob.com/lua/lua-tutorial.html

  直接用 SciTE 進行文本編輯,F5調試,非常方便。

注意點:

1. 變量的作用域:全局變量、局部變量- local 聲明,do - end 可以用於划分作用域。

2. 對多個變量賦值要逐個賦值,不可 a, b, c = 0。必須是 a, b, c = 0, 0, 0。

3. 運算符居然不能用 “++”、“+=”,其他都跟C/C++類似。

4. 流程控制:

i = 0
while(i < 5)
do
    print(i)
    i = i + 1
end
x = 1
if(x > 0)
then
    print(x)
end
x = 1
repeat
    print(x)
    x = x + 1
until x == 5
for i=1,5,1 do  --以步長為1從1遞增到5
    print(i)
end

a = {{1,2}, {2, 4}, {3, 6}}
for i,v in ipairs(a) do
    print(i, v[1], v[2])
end

5. 函數(其實也是變量)也可以用 local 修飾為局部

常規定義:

function max(num1, num2)  --函數聲明-函數名-參數列表
    if(num1 > num2) then
        result = num1;
    else
        result = num2
    end

    return result
end

print(max(1, 3))
print(max(5, 8))

多返回值:

function max(num1, num2)  
    if(num1 > num2) then
        result = num1;
    else
        result = num2
    end
    return 2, result
end

_, a = max(1, 3)
_, b = max(5, 6)
print(a)
print(b)

可變參數:

function average(...)
    local args = {...}
    result = 0

    for k,v in ipairs(args) do
        result = result + v
    end

    result = result / #args
    return result
end

print(average(1,4,5,10))

6. 字符串的表示:‘’、“”、[[ ]]。

7. 字符串常用處理api:

str_test = "Hello Lua"
print(str_test)
pos = string.find(str_test, "Lua", 1) --#3為開始檢索的偏移
print(pos)

str_test = string.format("I am learn Lua for %d hous.", 2)
print(str_test)
print(string.len(str_test))

print(str_test .. " It.s amazing.")      --連接字符串

print(string.byte("Test", 1))  --將字符串的字符轉為ascii
print(string.char(99))         --將ascii轉為字符

8. 數組用 {} 來定義。

array = {{1, 2}, {2, 4}, {4, 8}}

for i=1,3 do
    for j = 1,2 do
        print(array[i][j])
    end
end

9. 迭代器:ipairs,上面已經有使用。

10. table:數組不也是table么#83,只是它只存數字?

常用操作:

fruits = {"apple", "banana", "orange"}

print(table.concat(fruits))       --將每個子項直接相連
print(table.concat(fruits,", "))  --將子項之間通過", "相連
print(table.concat(fruits, ", ", 1, 2))  --將前2項相連,舍棄第3項

table.insert(fruits, "watermalon")  --在末尾插入
print(fruits[4])

table.insert(fruits, 2, "pomelo")   --在第2個位置插入
print(fruits[2])

table.remove(fruits, 2)  --移除第2個位置的項
print(fruits[2])

table.sort(fruits)   --排序
for k,v in ipairs(fruits) do
    print(v)
end

table.sort(fruits, function (fruit_1, fruit_2) return string.len(fruit_1) > string.len(fruit_2) end)    --自定義排序
for k,v in ipairs(fruits) do
    print(v)
end

之前寫多了C#,這幾天開始用 Lua,就老是把 C#的List 與 Lua的table 用混:

  C#:從 List 查找出的是數據的引用,用局部變量=引用,對該局部變量的任何修改,就是對 List 成員的修改。

  Lua:從 table 查找出的是數據的值,用局部變量=值,對該局部變量的任何修改,對 table 的成員是沒有任何作用的。

 table 是引用傳遞

 

11. 元表

設置元表與__index(類的成員定義、查找):

other = { member_1 = "A", member_2 = "B" }     --基礎表元素
entity_1 = setmetatable({ member_0 = "Words" }, { __index = other })    --添加元表

print(entity_1.member_0)    --打印基礎元素
print(entity_1.member_1)    --打印元表中的第一個元素
print(entity_1.member_2)    --打印元表中的第二個元素

entity_1 = setmetatable( entity_1, {    --元表元素也可以是函數,一切都是變量
    __index = function(entity_1, key)
        if key == "key2" then
            return "metatablevalue"
        else
            return nil;
        end
    end })

print(entity_1.key2)

__index:當你通過鍵來訪問 table 的時候,如果這個鍵沒有值,那么Lua就會尋找該table的metatable(假定有metatable)中的__index 鍵。如果__index包含一個表格,Lua會在表格中查找相應的鍵。

Lua查找一個表元素時的規則,其實就是如下3個步驟:

  • 1.在表中查找,如果找到,返回該元素,找不到則繼續
  • 2.判斷該表是否有元表,如果沒有元表,返回nil,有元表則繼續。
  • 3.判斷元表有沒有__index方法,如果__index方法為nil,則返回nil;如果__index方法是一個表,則重復1、2、3;如果__index方法是一個函數,則返回該函數的返回值。

 

__newindex(更新成員):

調用__newindex元方法,來控制對元表元素的更新。

mymetatable = {}
mytable = setmetatable({key1 = "value_1"}, {__newindex = mymetatable})    --省略了 function(mymetatable, key, value)

print(mytable.key1)

mytable.newkey_1 = "newvalue_2"
print(mytable.newkey_1, mymetatable.newkey_1)    --nil, newvalue_2
son_entity = { son_member = "son_value", __index = { son_metamember = "son_metavalue"},
        __newindex = function(table, key, value)
        print(key.." is not exist.")
        end
    }

parent_entity = { parent_member = "parent_value" }
setmetatable(parent_entity, son_entity)

print(parent_entity.parent_member)
print(parent_entity.son_member)
print(parent_entity.son_metamember)
parent_entity.newkey = 1
--output: parent_value、nil、son_metavalue、newkey is not exist

如果__newindex是一個函數,則在給table不存在的字段賦值時,會調用這個函數。
如果__newindex是一個table,則在給table不存在的字段賦值時,會直接給__newindex的table賦值。

 

運算符重寫:

__add、__sub、__mul、__div、__mod、__unm、__concat、__eq、__lt、__le,這些運算符可重寫。

entity_1 = setmetatable( {1, 2, 3}, {
    __add = function(genericT, num)
    for k, v in ipairs(genericT) do
        genericT[k] = v + num
        end
    return genericT
    end
})

--[[
entity_1 = setmetatable( {1, 2, 3}, {
    __add = function(genericT, num)
    for k, v in ipairs(genericT) do
        v = v + num        --最初的寫法是這樣
        print(v)        --這里打印的數據會被修改,但並不會真正改到 entity_1
        end                --可見lua的迭代器是值傳遞,還不是C#的引用傳遞
    return genericT
    end
})
]]--

entity_1 = entity_1 + 5

for k, v in ipairs(entity_1) do
    print(v)
end

 

元方法(構造函數)

定義方法 __call:

person = { name = ""}
person = setmetatable( person, {
    __call = function(person, newname)
        person.name = newname
    end
})

person("Luakid")
print(person.name)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM