一些感觉不足以单独开一篇文章写的lua相关内容,我都会尽量的放在这里。
不止是八股,也会有一些平常学习的小心得。
目前有点乱,以后内容补充多了会整理切分
nil
local x = nil
if x == nil then
print("x is nil")
endboolean
local enabled = false
if enabled then
print("Feature is enabled")
else
print("Feature is disabled")
endnumber
local num = 10
local result = num * 2
print(result) -- 输出 20local str = "Hello, World!"
print(str) -- 输出 Hello, World!
print(string.len(str)) -- 输出 13table
local table = {"apple", "banana", "cherry"}
for i, fruit in ipairs(table) do
print(i .. ": " .. fruit)
end
-- 输出
-- 1: apple
-- 2: banana
-- 3: cherry function
local add = function(a, b)
return a + b
end
print(add(1, 2)) -- 输出 3userdata
local ptr = ffi.new("int[10]")
ptr[0] = 42
print(ptr[0]) -- 输出 42thread
local co = coroutine.create(function()
print("Inside coroutine")
end)
coroutine.resume(co) -- 输出 "Inside coroutine"local x = "hello"
if type(x) == "string" then
print(x .. " is a string")
endlocal num = tonumber("123") -- string类型转为number类型
print(num + 1) -- 输出 124在 Lua 中,面向对象编程主要是通过元表(metatable)和表(table)来实现的。Lua 不像其他语言那样有类的概念,而是使用表来模仿类的行为。
对象的概念
在 Lua 中,一个表(table)可以被视为一个对象。每个对象都有自己的状态(数据成员)和行为(成员函数)。
对象实现思路
封装
封装是指将数据和操作数据的方法绑定在一起,隐藏对象的具体实现细节。在这个过程中,我们定义一个类(即原型对象),从这个类派生出具体的对象。每个具体的对象都有自己的状态(成员变量),并通过成员函数来操作这些状态。
为了实现这一过程,我们可以将原型对象作为具体对象的元表(metatable),这样当具体对象找不到某个方法时,就会去原型对象中查找。此外,具体对象通过 self 来在成员函数中调用自身的成员变量。
继承
继承允许子类继承父类的特性和行为。在这个过程中,我们同样可以从父类的类对象派生出子类的类对象。子类可以覆盖或扩展父类的行为。
当子类定义了与父类同名的函数时,由于子类可以直接找到这些函数,因此不会去父类中查找,这就导致了子类会隐藏父类的同名函数。
多重继承
多重继承允许一个子类继承多个父类的功能。在实现多重继承时,我们需要保存传递过来的所有父类对象,并形成一个父类列表。
然后,我们可以设置子类的元表的 __index 属性为一个查找函数。这个查找函数会在父类列表中遍历,寻找相应的字段或方法。
私有性
私有性是指只有对象自身可以访问其内部状态,外部代码无法直接访问这些状态。为了实现私有性,我们可以利用局部变量和闭包。
具体来说,可以创建一个表来保存私有变量,另一个表来保存公共的字段和接口函数。内部的公共函数通过闭包来访问私有成员变量,并将包含公共接口的表返回出去。
详细实现可参考笔者的另一篇文章
要创建一个只读表,可以使用元表中的 __newindex 方法来阻止对表的任何修改:
深色版本
local ro_table = setmetatable({}, {
__newindex = function()
error("Attempt to modify a read-only table")
end
})
ro_table.x = 1 -- 这将抛出错误全局禁用
-- 设置全局表的元表 禁止创造全局变量
setmetatable(_G, {
__newindex = function(t, key, value)
print("Cannot create global variable '" .. key .. "'")
end
})Lua 与 C 的交互主要通过 Lua 的 C API 实现。在 Lua 中,所有的值都是放在栈上的。Lua 的 C API 提供了一系列的函数来从 C 调用 Lua 代码,并从 Lua 调用 C 函数。

Lua 使用引用计数和周期性的全局扫描(mark-and-sweep)来实现垃圾回收。当一个值不再被引用时,它会被回收。GC 过程包括几个阶段:
在 Lua 的垃圾回收(GC)过程中,对象的状态通常被分为三类:黑色(black)、灰色(gray)和白色(white)。这些颜色用来表示对象的状态,以便进行标记-清扫(mark-and-sweep)算法的实现。下面详细解释每种颜色的意义:
标记-清扫算法是 Lua 中垃圾回收的基本算法。它分为两个主要阶段:
标记(Marking):
Lua 的 table 结构实际上是由一个数组部分和一个哈希表部分组成的混合结构。数组部分用于快速访问连续的索引(通常是数字),而哈希表部分用于非连续的索引或其他类型的键。
遍历方法
Lua 中有三种常见的遍历表的方法:
for i, v in ipairs(my_table) do
print(i, v)
endnext
next 函数手动遍历表。
需要显式地管理迭代状态。
local k, v = next(my_table)
while k do
print(k, v)
k, v = next(my_table, k)
endLua 中的字符串一旦创建就不会改变,并且相同内容的字符串在内存中只会保存一份。这意味着如果你有两个字符串字面量 "hello",它们实际上指向同一个内存地址。
当 Lua 中的值被传递给 C 函数时,可以使用 luaL_ref 来保存这个值的引用,从而防止它被垃圾回收。当不再需要这个值时,使用 luaL_unref 释放引用。
闭包是一个函数与其相关的引用环境组合而成的一个整体。在 Lua 中,闭包允许函数访问其外部作用域中的变量,即使该函数在其定义的作用域之外被调用也是如此。
local x = 10
local function f()
print(x)
end
x = 20
f() -- 输出 20在这个例子中,f 是一个闭包,因为它记住了定义它的上下文中 x 的值。即使 x 的值后来改变了,f 仍然可以访问到原始的 x 的值。
一开始只是想做一个面试碰到,或者网上面经总结的Lua八股笔记,在腾讯云开发者社区写习惯以后在别的地方写文章总觉得有点别扭,于是干脆把本地写的内容放在腾讯云社区。
以后再碰到相关八股内容也会补充到这篇文章
并且尽量让内容不止于八股,而是可以从八股衍生出去思考。
当然笔者的水平有限,答案以参考lua手册和ai回答以及网上文章得出,其中纰漏谬误难以避免,若能指出,不胜感激。
若有侵权也可联系笔者指出删除(⊙﹏⊙)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。