Lua再學習

因為實習的項目用到了Lua,所以再來深入學習一下

函數

函數的的多返回值

Lua中的函數可以實現多返回值,實現方法是再return后列出要返回的值的列表,返回值也可以通過變量接收到,變量不夠也不會影響接收對應位置的返回值

Lua中傳入參數和參數個數不匹配也不會報錯,只會補空或丟棄

函數的重載

在Lua中他是不支持函數的重載的,默認調用最后聲明的這個函數,但是使用重載的方法也不會報錯

變長參數

變長參數在函數內使用時需要先用一個表存起來,然后再去操作

function add(...)  
local s = 0  for i, v in ipairs{...} do   --> {...} 表示一個由所有變長參數構成的數組  s = s + v  end  return s  
end  
print(add(3,4,5,6,7))  --->25

函數嵌套

function F8(x)return function(y)//不需要命名return x+yend
end
f9=F8(10)//相當于返回一個函數類型的變量
print(f9(5))//15

這也是Lua中閉包的體現
改變傳入參數的生命周期
傳入參數x本應在執行完之后被銷毀,但因為閉包改變了x的生命周期讓其可以持續存在

table

lua中所有的復雜類型都是table,數組二維數組字典類都是用table實現的
數組
lua中索引從1開始
a={1,2,4,“123”}
#是通用的獲取長度的關鍵字
如果表中某一位為nil會影響#獲取長度(5.1已改),長度從nil開始截斷
二維數組

a={{1,2,3},{4,5,6}}
for i=1,#a dob=a[i]for j=1,#b doprint(b[j])end
end

table實現類

lua中復雜一點的數據結構都是通過類來實現的
lua中沒有面向對象的概念,需要我們自己來實現

Student={age=1,sex=true,Up=function()//函數體//在表內部的函數調用表內部的變量必須要指定是誰的print(Student.age)end,Learn=function(t)//把自己作為參數傳進來print(t.age)//函數體end
}
//不像C#一樣需要new一個對象來實現調用
Student.Up()
//可以在表外申明表的變量和方法
Student.name="111"
Student.Speak=function()
end
function Student.Speak2()
end
//冒號會把調用者作為第一個參數傳入
//如果使用冒號申明函數,相當于有一個默認參數
Student:Learn()
Student.Learn(Student)

協程

協程的創建
協程的創建一般依附于一個函數
協程的本質是一個線程對象

--常用方式
--返回的是一個線程
fun=function()
end
co=coroutine.create(fun)
--返回的是一個函數
co2=coroutine.wrap(fun)

協程的運行
兩種創建方式對應的運行方式也不同

coroutine.resume(co)
--因為協程返回的是一個函數,所以可以直接運行
co2()

協程的掛起

fun2=function()while ture doprint("123")--掛起函數coroutine.yield()//協程也可以返回值--coroutinre.yield(i)end
end
co3=coroutine.create(fun2)
--區別于C#的協程,lua中的協程每調用一次執行一次對應的函數
coroutine.resume(co3)
-- 默認第一個返回值是協程是否啟動成功--這種方式的協程調用也可以有返回值,只是沒有默認第一個返回值了
co4=coroutine.wrap(fun2)
co4()
co4()

協程的狀態
dead結束
running運行
suspended暫停

coroutine.status(協程對象)
--獲取正在運行的協程的協程號
coroutine.running()

元表

元表概念
任何表變量都可以作為另一個表變量的元表
任何表變量都可以有自己的元表
當我們子表(有元表的表)進行一定操作時會執行元表中的內容

設置元表

mete={}
mytable={}
--設置元表函數,第一個參數子表,第二個參數元表
setmetatable(mete,mytable)
getmetatable(mete)--獲得子表對應的元表

元表的特定操作

__tostring(用的多)

mete={--當子表要作為字符串使用時,會默認調用元表中的__tostring 方法__tostring=function(t)return t.nameend
}
mytable={name="123"
}
setmetatable(mete,mytable)
print(mytable)--輸出123

__call(用的多)

mete={--當子表被當作一個函數來使用時,會默認調用這個__call中的內容--當希望傳參數時第一個參數一定是調用者自己__call=function(a,b)print(a)print(b)end
}
mytable={name="123"
}
setmetatable(mete,mytable)
print(mytable)
--輸出123
1

運算符重載(用的可能不多)

mete={--相當于運算符重載 當子表使用對應運算符時會調用該方法-- +__add=function(a,b)return a.name+b.nameend,-- ==調用的兩個表的元表必須一致,才能準確調用此方法__eq=function(a,b)return trueend
}
mytable={name=1
}
mytable2={name=2
}
setmetatable(mete,mytable)
print(mytable+mytable2)
--輸出123
1

__index

mete={}
meta.__index={age=2}
-- __index的賦值寫在表外面來初始化,和C++的構造函數不可以是虛函數一個道理,自己都沒有初始化好要怎么指向自己內部的東西呢
mytable={}
setmetatable(mete,mytable)
__index:當子表中找不到某一個屬性時,會到元表中__index指定的表去找屬性
print(mytable.age)--輸出2

__index還可以實現“套娃”,當子表中找不到某一個屬性時,會到元表中找這個屬性,如果元表中也找不到該屬性則會到元表的元表中去尋找

__newIndex

__newIndex當賦值時,如果賦值一個不存在的索引,那么會把這個值賦值到__newIndex所指的表中,不會修改自己

mete={}
meta.__newIndex={}
mytable={
}
setmetatable(mete,mytable)
mytable.age=1
print(mytable.age)--輸出2

使用rawget和rawset可以直接設置對應的表,而非索引指向的元表

實現面向對象

表就是表現類的一種形式

在Lua中,冒號語法糖用于簡化方法的定義和調用,自動傳遞self參數。當用冒號定義方法時,實際上隱式地添加了self作為第一個參數。例如,obj:method() 轉換成 obj.method(obj)
如果用點號調用時冒號聲明的方法,需要顯式傳遞self。

封裝

聲明對象實際上是聲明了一張空表,獲取屬性是通過設置元表后獲取元表的屬性實現的

--self代表的是我們默認傳入的第一個參數
--對象就是變量,返回一個新的變量
--返回出去的內容本質是一個表對象Object={}
Object.id=1
function Object:Test()print(self.id)
endfunction Object:new()local obj={}--當子表中找不到某一個屬性時,會到元表中__index指定的表去找屬性self.__index=selfsetmetatable(obj,self)return obj
endlocal myobj=Object:new()
myobj:Test()--輸出1
對空表中申明一個新的屬性叫做id
myobj.id=2
myobj:Test()--輸出2

繼承

接上文
_G來根據字符串創建一個新的表(類)
在這里插入圖片描述

function Object:subClass(classNmae)-- _G是總表 所有聲明的全局標量 都以鍵值對的形式存在在其中_G[className]={}local obj=_G[className]self.__index=selfsetmetatable(obj,self)
end
Object:subClass("Person")
local p1=Person:new()
print(p1.id)--輸出1

多態

多態的本質是相同的方法執行不同的邏輯

代碼接上文
方法1:子類直接重寫這個方法
方法2:通過給子類添加base屬性保留父類邏輯執行

function Object:subClass(classNmae)-- _G是總表 所有聲明的全局標量 都以鍵值對的形式存在在其中_G[className]={}local obj=_G[className]self.__index=self-- 為子類定義base屬性 base屬性代表父類obj.base=selfsetmetatable(obj,self)
endObject:subClass("GameObject")
GameObject.PosX=0
GameObject.PosY=0function GameObject:Move()self.PosX=self.PosX+1self.PosY=self.PosY+1
end
Object:subClass("Player")function Player:Move()
-- base指的是GameObject表()
-- 這種調用方式相當于是把基類表作為第一個參數傳入了方法中self.base:Move()
endlocal p1=Player:new()
p1:Move()
local p2=Player:new()
p2:Move()

目前這種寫法有坑,不同對象使用的成員變量是相同的成員變量,不是自己的

更正版

function Player:Move()
-- 如果我們要執行父類邏輯,則需要避免將父類傳入到方法中
-- 所以要使用.去調用,自己傳入第一個參數self.base.Move(self)
end

總結

Object={}
Object.id=1
function Object:new()local obj={}--給空對象設置元表和__indexself.__index=selfsetmetatable(obj,self)return obj
endfunction Object:subClass(classNmae)-- 根據名字生成一張表,即一個類_G[className]={}local obj=_G[className]--給子類設置元表以及__indexself.__index=self--設置自己的父類obj.base=selfsetmetatable(obj,self)
end--申明一個新的類
Object:subClass("GameObject")
--成員變量
GameObject.PosX=0
GameObject.PosY=0
--成員方法
function GameObject:Move()self.PosX=self.PosX+1self.PosY=self.PosY+1
end-- 實例化對象使用
local obj=GameObject:new()
obj:Move()--申明一個新的類,Player繼承GameObject
Object:subClass("Player")--重寫了Move方法
function Player:Move()
--base調用父類方法,自己傳第一個參數self.base.Move(self)
endlocal p1=Player:new()
p1:Move()

垃圾回收

collectgarbage

test={id=1}
-- lua中的機制和垃圾回收很類似,置空之后就認定為垃圾
test=nil
--進行垃圾回收,理解有點像C#的GC
collectgarbage("collect")
--獲取當前lua占用內存數
collectgarbage("count")

lua中有自動定時進行GC的方法
但是在熱更新開發中通常不會使用自動GC,而是選擇在內存占用量達到一定程度時手動GC,減少性能損耗

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80981.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80981.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80981.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TCP協議十大核心特性深度解析:構建可靠傳輸的基石

TCP(傳輸控制協議)作為互聯網的"交通指揮官",承載著全球80%以上的網絡流量。本文將深入解析TCP協議的十大核心特性,通過原理剖析、流程圖解和實戰案例,揭示其如何實現高效可靠的數據傳輸。 一、面向連接的可…

基于 Spring Boot 瑞吉外賣系統開發(十三)

基于 Spring Boot 瑞吉外賣系統開發(十三) 查詢套餐 在查詢套餐信息時包含套餐的分類名,分類名稱在category表中,因此這里需要進行兩表關聯查詢。 自定義SQL如下: select s.* ,c.name as category_name from setmeal…

華為IP(6)

VLAN聚合 VLAN聚合產生的技術背景 在一般是三層交換機中,通常采用一個VLAN接口的方式實現廣播域之間的互通,這在某些情況下導致了IP地址的浪費 因為一個VLAN對應的子網中,子網號、子網廣播地址、子網網關地址不能用作VLAN內的主機IP地址&a…

深度解析IP靜態的工作原理,IP靜態的應用場景又哪些?

一、什么是IP靜態? 當我們談到“IP靜態”時,大家可能首先想到的是與“動態IP”相對的概念。確實如此,靜態IP是一種固定分配的IP地址,也就是說,在特定時間內,分配給你的IP地址不會有所更改——無論你完成多…

docker(四)使用篇一:docker 鏡像倉庫

前文我們已經介紹了 docker 并安裝了 docker,下面我們將正式步入使用環節,本章是第一個使用教學:docker 鏡像倉庫。 一、什么是鏡像倉庫 所謂鏡像倉庫,其實就是負責存儲、管理和分發鏡像的倉庫,并且建立了倉庫的索引…

單片機開發軟件

目錄 純編碼 vscode Ardunio Keil 1. 集成化開發環境(IDE) 2. 多架構芯片支持 3. 高效的代碼生成與優化 4. 強大的調試與仿真功能 5. 豐富的庫函數與生態系統 6. 教育與企業級適用性 典型應用場景 半編碼半圖形化 STM32CUBEIED 1. 圖形化配置…

【虛幻引擎】UE5獨立游戲開發全流程(商業級架構)

本套課程我將會講解一下知識 1.虛幻引擎的常用功能節點、模塊包含但不限于動畫模塊、UI模塊、AI模塊、碰撞模塊、傷害模塊、背包模塊、準心模塊、武器模塊、可拾取物品模塊、死亡等模塊。 2.整個游戲的設計思路(游戲架構),本套教程講解了如…

ABP-Book Store Application中文講解 - Part 2: The Book List Page

本章用于介紹如何創建Book List Page。 TBD 1. 匯總 ABP-Book Store Application中文講解-匯總-CSDN博客 2. 前一章 ABP-Book Store Application中文講解 - Part 1: Creating the Server Side 項目之間的引用關系。 目錄 1. 多語言配置 1.1 zh-Hans.json 1.2 en.jso…

6、登錄功能后端開發

6、登錄功能后端開發 https://xiaoxueblog.com/ai/%E7%99%BB%E5%BD%95%E5%8A%9F%E8%83%BD%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91.html 1、新建用戶表SQL腳本 -- CREATE DATABASE aicloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;-- 創建用戶表 drop table if exi…

隨機矩陣放大的方式 生成相位數據集,用于相位展開

import os import numpy as np import matplotlib.pyplot as plt from scipy.ndimage import zoom import gc from tqdm import tqdm from zernike import RZerndef wrap_phase(phase):"""將相位包裹到[-π, π]區間"""return np.angle(np.exp(1…

Java面試全記錄:Spring Cloud+Kafka+Redis實戰解析

Java面試全記錄:Spring CloudKafkaRedis實戰解析 人物設定 姓名:張偉(隨機生成唯一姓名) 年齡:28歲 學歷:碩士 工作年限:5年 工作內容: 基于Spring Cloud搭建微服務架構使用Kafka…

Java Socket編程完全指南:從基礎到實戰應用

Socket編程是構建網絡應用的基石,Java通過java.net包提供了強大的Socket API。本文將深入解析Java Socket類的核心用法,涵蓋TCP/UDP協議實現、多線程通信及性能優化技巧,助您快速掌握網絡編程精髓。 一、Socket編程核心概念 1.1 網絡通信模型…

vue實現導出echarts圖片和table表格

安裝依賴 "xlsx": "^0.18.5","xlsx-style": "^0.8.13""file-saver": "^2.0.5",工具類 toolUtil const autoHeight () > {let winHeight 0if (window.innerHeight) {winHeight window.innerHeight} else if…

AI預測3D新模型百十個定位預測+膽碼預測+去和尾2025年5月15日第78彈

從今天開始,咱們還是暫時基于舊的模型進行預測,好了,廢話不多說,按照老辦法,重點8-9碼定位,配合三膽下1或下2,殺1-2個和尾,再殺6-8個和值,可以做到100-300注左右。 (1)定…

蘭亭妙微B端UI設計:融合多元風格,點亮品牌魅力

在B端產品市場,獨特的品牌形象是企業脫穎而出的關鍵。蘭亭妙微專注于B端UI設計,通過融合多元風格,為企業點亮品牌魅力,助力品牌價值提升。 蘭亭妙微主創團隊源自清華,歷經多年沉淀,積累了豐富的設計經驗。…

MMTEA-DTS--用于多目標多任務優化的基于分解的遷移選擇

MMTEA-DTS–用于多目標多任務優化的基于分解的遷移選擇 title: Multiobjective Multitasking Optimization With Decomposition-Based Transfer Selection author: Qiuzhen Lin, Zhongjian Wu, Lijia Ma, Maoguo Gong , Jianqiang Li, and Carlos A. C…

Python機器學習筆記(二十三 模型評估與改進-網格搜索)

上一次學習了評估一個模型的泛化能力,現在繼續學習通過調參來提升模型的泛化性能。scikit-learn中許多算法的參數設置,在嘗試調參之前,重要的是要理解參數的含義。找到一個模型的重要參數(提供最佳泛化性能的參數)的取值是一項棘手的任務,但對于幾乎所有模型和數據集來說…

集成DHTMLX 預訂排期調度組件實踐指南:如何實現后端數據格式轉換

在企業級應用中,預訂系統(Booking System)作為典型的調度類應用,廣泛用于酒店、會議室、設備預約、醫療排班等業務場景。而DHTMLX Scheduler作為一款功能強大且高度可定制的 JavaScript 日程安排控件,已成為眾多開發者…

35頁AI應用PPT《DeepSeek如何賦能職場應用》DeepSeek本地化部署與應用案例合集

這份名為《DeepSeek如何賦能職場應用》的PPT文檔詳細介紹了DeepSeek這一人工智能工具在職場中的多樣化應用場景和操作技巧。內容涵蓋了從基礎模型到深度思考模型的不同功能,以及如何通過提示語技巧實現高效的人機協作。文檔還展示了DeepSeek在制作可視化圖表、PPT、…

Axure疑難雜癥:母版菜單設置打開鏈接后菜單選中效果

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 課程主題:菜單打開鏈接后子菜單選中效果 主要內容:母版設計、選中效果 應用場景:頁面賦值 案例展示: 案例視頻: