Lua - 类型和值

本文介绍了Lua中的基本值类型,包括nil、number、string、bool、function和userdata,详细解析了每种类型的特性和用途。此外,还探讨了Lua唯一的结构类型——Table,作为数组、哈希表及模拟面向对象的基础,强调了其灵活性和可读性。在Lua中,Table用于模拟数组和哈希表,而面向对象的类则是通过Table和元表机制实现的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lua中的值类型

空值 nil

lua中的空值与其他语言null类似,用关键字nil表示。

数字 number(double)

lua中的数字均以双精度浮点数存放,不存在整数和浮点数的区别,不过在lua的语法说明里面也明确表示,编译时时可以用整数和单精度浮点数表示的。

字符串 string

lua中的字符串与其他语言类似,并且在lua里,没有字符型的数据,单个字符也是作为字符串存放的。

布尔 bool

lua中的布尔值与其他语言类似,但是在lua中,空字符串和0都是true,这在之后的逻辑表达式里提供了很大的方便。

function

在lua里,函数实际上是作为一种值存在,可以作为变量存取,可以作为其他函数的参数,甚至作为返回值。

userdata

这个个人理解为一种指针,在与其他语言交换数据时,实际上交换的就是这样一个东西。在使用Unity的过程中,经常碰到物件销毁后判断是否为空的情况,而Unity销毁物件后,lua里的这种“指针”仍然指向那个物体,所以这种情况必须使用GameObject:Equals(nil)这样的方式去判断其是否为空,以后会有详细的说明。

Lua中的结构类型

Table

在Lua里,Table是唯一的一种数据结构,存放数据的方式是键值对key = value。强大,方便,容易理解。其他语言中的数据结构都可以通过Table来实现。之后的面向对象也是通过Table去模拟类的行为。
同时,键值对的直观性也让Lua语言有很好的可读性。越来越多的人开始使用Lua作为配置文件使用。

数组

用Table模拟数组,只需要在Table里按顺序放入value就行,key的值自动从1开始。

array = { 1, 3, 5, 7, 9 };

-- 想要得到数组长度,可以使用下面的方法
print(#array, table.getn(array));   --> 5   5

-- 数组的下标从1开始
print(array[0]);    --> nil;
print(array[1]);    --> 1;
print(array[5]);    --> 9;

不过这样模拟的数组不会有越界报错,只可能出现空值(nil)报错,因为在Lua里变量不用事先声明,而这样的数组只是一连串的变量而已。

array = { 1, 3, 5, 7, 9 };
print(array[10]);   --> nil
array[9] = 0;
print(array[9]);    --> 0
print(array[10].."");   --> error:attempt to concatenate a nil value

运行上面的例子可以发现,在使用array的过程中没有出现任何异常错误,甚至可以赋值!但是当你把它作为参数用在别的地方,而你之前又未对它进行赋值时,就会出现错误了。这个问题当然也是可以通过设计去解决的,这在以后研究模拟面向对象时会讲解。

哈希表

Table和哈希表都是一种通过索引去访问的键值对,几乎是等价的。

hashmap = {};

function Print()    -- 遍历输出表的内容
    local str = "";
    for k, v in pairs(hashmap) do
        str = str..k..": "..v..";\t"
    end
    print(str);
end

hashmap[0] = "a";               -- 直接通过索引加入值
table.insert(hashmap, "b");     -- table.insert()可以在表中插入值,不指定插入位置,会自动放在表最后
hashmap.a = "c";                -- 使用点号也可以通过变量名索引
Print();    --> 0: a;   1: b;   a: c;
-- 删除元素直接让键值对中的value为nil就可以
hashmap[0] = nil;
table.remove(hashmap, 1);
hashmap.a = nil;
Print();    -->

以上两种是目前想到的,不需要任何设计就可以实现的两种结构(实际上是通过Lua访问Table成员的方式去模拟)。

面向对象的类

用Lua去模拟面向对象的类,需要掌握很多相关的语法知识,其中比较晦涩难懂的,就是元表metatable和__index元方法,这些会在以后进行详细的整理。

这里想事先说明的,不管是怎么模拟的面向对象,Lua的基本语法里没有私有性,没有静态动态,没有继承派生,变量不需要事先声明,也没有规定你必须有构造和析构方法,所有的一切,都是通过设计去模拟面向对象的各种特性。Lua的简单灵活是它的优势,口头规定的规则不能保证程序的稳定性。

Class = {
    className = "Class";
    name;
    value;
};
Class.__index = Class

function Class.New(name, value)
    local self = {};
    setmetatable(self, Class);
    self.name = name;
    self.value = value;
    return self;
end

function Class:SetValue(value)
    self.value = value;
end

function Class:Print()
    print(self.name, self.value);
end

obj1 = Class.New("obj1", 1);
obj2 = Class.New("obj2", 2);
obj1:Print();   --> obj1    1
obj2:Print();   --> obj2    2
obj1:SetValue(3);
obj1:Print();   --> obj1    3
obj2:Print();   --> obj2    2

以上是一个简单的面向对象例子,理解起来应该不难。在之后的文章中,我会整理出几个重要的设计,来实现一些常用的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值