当前位置:

首页 > 编程开发 > Lua中基本的数据类型、表达式与流程控制语句讲解

Lua中基本的数据类型、表达式与流程控制语句讲解

Lua提供8种基本类型:nil、boolean、number、string、table等,只有false和nil为假,number为双精度浮点,字符串不可变,table索引从1开始。表达式包含算术、关系、逻辑运算符及连接符..,支持自动类型转换。控制结构有if、while、repeat-until、数字型for和泛型for,均以end或until结尾。

本文目录

    Lua 作为一种动态类型语言,其类型系统设计得非常灵活,没有传统静态语言那种繁琐的类型定义语法。今天我们来系统梳理一下 Lua 的 8 种基础类型,以及在实际使用中容易被忽略的细节。

    1. Lua 类型

    1.1 基本类型

    Lua 一共提供了 8 种基础类型:nil(空)、boolean(布尔)、number(数字)、string(字符串)、userdata(自定义类型)、function(函数)、thread(线程)、table(表)。

    通过内置的 type 函数,你可以随时获取任意值的类型名称(返回字符串)。举个例子:print(type(print)) 会输出 "function";而 print(type(type(X))) 则输出 "string" —— 无论 X 是否定义,type(X) 始终返回一个字符串,所以外层 type 拿到的永远是一个字符串类型。

    1.2 各类型要注意的地方

    关于 boolean:

    在 Lua 中,只有 false 和 nil 被视为“假”,其他所有值(包括数字 0 和空字符串)都被视为“真”。这一点和很多语言不太一样,写条件判断时要特别留意。

    关于 number:

    Lua 的 number 类型实际上就是双精度浮点数(double),整数也用它来表示。所以不用担心精度问题——只要在 double 能精确表达的整数范围内,运算结果都是准确的。

    关于 string:

    字符串是不可变的,你不能像 C 语言那样直接修改某个字符。如果需要修改,必须通过 string 库创建新字符串。字符串可以用单引号或双引号界定,也支持 C 风格的转义序列(比如 \n 换行)。

    一个比较方便的特性是,你可以用双方括号 [[内容]] 来定义多行字符串,其中的换行符会被原样保留。更妙的是,如果在左边方括号间加入任意数量的等号(比如 [===[),那么结束标记也必须使用相同数量的等号(比如 ]===])。这样一来,字符串里即使包含原始的双括号内容,也不需要转义。这个技巧同样适用于注释:--[==[ 注释内容 ]==]。

    Lua 在运行时支持数字与字符串的自动转换。例如 print("10" + 1) 输出 11,print(10 .. 20) 输出 "1020"(.. 是字符串连接符,注意数字和 .. 之间要加空格以避免歧义)。不过建议尽量少依赖自动转换,显式使用 tonumber(x) 和 tostring(x) 更安全。tonumber 转换失败时返回 nil。要获取字符串长度,可以在字符串前加 # 运算符,比如 print(#"length") 输出 6。

    关于 table:

    Table 是 Lua 中最核心的数据结构,它可以看作一种具有特殊索引方式的数组,允许使用除 nil 外的任何类型作为索引。Table 的增删都通过自动内存管理完成,你不需要手动释放。注意,table 是一个“对象”,变量只持有对它的引用——比如 a = {} 创建了一个 table,然后 b = a 会让 b 和 a 指向同一个 table。如果某个元素没有初始化,其值就是 nil,而将某个元素赋值为 nil 就可以删除它。

    访问 table 时有两种等价写法:p["age"] 等价于 p.age。但 p.age 和 p[age] 完全不是一回事——后者中的 age 是一个变量。

    # 运算符可以返回数组的最后一个索引(即大小)。例如 print(a[#a]) 打印最后一个元素,a[#a+1] = io.read() 则是在末尾追加一个值。不过要注意,Lua 把 nil 当作数组的结束标志,如果数组中间含有 nil,# 会认为第一个 nil 就是结尾。因此,尽量避免对存在“空隙”的数组使用 #。

    需要强调的是,Lua 中 table 默认索引从 1 开始,而不是 C 语言的 0,这一点在后续使用中要特别留意。

    Function、userdata 和 thread 类型我们后面再详细展开。

    2. 表达式

    2.1 算术操作符

    常规操作符包括:+(加)、-(减)、*(乘)、/(除)、^(指数)、%(取模)。其中 ^ 可以用于任意实数,比如 x ^ (-1/3) 可以计算 x 的立方根倒数。% 的用法也很灵活:x % 1 得到 x 的小数部分,x - x % 0.01 则得到 x 精确到小数点后两位的值。

    2.2 关系操作符

    标准的关系操作符有:<(小于)、>(大于)、<=(小于等于)、>=(大于等于)、==(相等)、~=(不等)。== 和 ~= 可以用于任意两个值,如果类型不同则不相等。相同类型则进行正常比较(nil 只与自身相等)。对于 table 这类对象,比较的是它们的引用。

    2.3 逻辑操作符

    逻辑操作符有 and、or 和 not。对于 and,如果第一个操作数为假,就返回第一个操作数,否则返回第二个操作数。对于 or,如果第一个操作数为真,就返回第一个操作数,否则返回第二个。比如 print(4 and 5) 输出 5,print(false or 5) 输出 5。

    利用这个特性可以写出很简洁的代码:x = x or v 相当于给 x 设置默认值 v(如果 x 未初始化)。而 (a and b) or c 则类似三元运算符 a ? b : c,比如 max = (x > y) and x or y。

    2.4 字符串连接符

    用两个点 .. 来连接字符串,如果其中任一个操作数是数字,Lua 会自动将其转换为字符串。例如 print(0 .. 1) 输出 "01"。注意连接操作会创建一个新字符串,原操作数不会被修改。

    Lua 运算符的优先级顺序如下图所示:

    2016617155955635.jpg (405×375)

    2.5 Table 构造式

    除了用 {} 创建空 table,也可以在创建时直接初始化。例如 days = {"S", "M", "T"} 会创建一个以数字为索引的列表,默认索引从 1 开始。再如 point = {x = 10, y = 20} 则等价于 point.x = 10; point.y = 20。这两种方式可以混用,甚至可以用分号代替逗号来明显分隔列表部分和记录部分:

    polyline = {color = "blue"; {x = 0, y = 0}, {x = 10, y = 10}, {x = 20, y = 30}}
    print(polyline[2].x)  -- 输出 10
    

    更通用的初始化格式允许在方括号间声明索引值,比如 opnames = {["+"] = "add", ["-"] = "minus"}。如果你确实需要以 0 作为数组起始索引,可以这样写:days = {[0] = "S", "M", "T"}。但强烈建议不要这样做——Lua 的大多数内建函数都假设数组起始于索引 1,硬要打破这个惯例只会给自己添麻烦。

    3. 顺序结构

    3.1 赋值

    除了常规的 = 赋值,Lua 还支持多重赋值,变量和值之间用逗号分隔。Lua 会自动调整等号右边的值个数,使其与左边变量个数匹配:如果值不够,多余的变量会被赋为 nil;如果值多了,多余的值会被丢弃。例如 a, b = 10, 2 * x,或者经典的交换 x, y = y, x。多重赋值最常见的用途就是交换变量,或接收函数返回的多个值。

    3.2 局部变量与程序块

    和很多语言一样,Lua 提供了局部变量,用关键字 local 声明。局部变量的作用域仅限于声明它的程序块(比如控制结构的执行体、函数体等)。注意,在交互模式中,每行输入本身就是一个程序块,所以单句 local 声明是无效的。如果想显式地界定一个块,可以用一对 do-end 关键字包裹起来,这在严格控制变量作用域时非常有用。

    有一种常见的写法:local foo = foo。这看起来有点奇怪,但实际上是用全局变量 foo 的值初始化一个同名的局部变量。这样做的目的是“缓存”当前值,避免后续其他函数修改全局变量时产生影响。

    4. 控制结构

    Lua 的所有控制结构都有显式的终止符:if、for、while 以 end 结尾,repeat 以 until 结尾。

    4.1 if then else(elseif) 语句

    标准格式如下:

    if <条件1> then
        <内容1>
    elseif <条件2> then
        <内容2>
    else
        <内容3>
    end
    

    Lua 没有 switch 语句,所以一连串 elseif 是很常见的写法。

    4.2 while 和 repeat 语句

    while 的格式:while <条件> do <循环体> end,先判断条件,再执行循环体。

    repeat 的格式:repeat <循环体> until <条件>,先执行一次循环体,再判断条件。注意,在 repeat 循环体内声明的局部变量,其作用域包括循环的条件测试部分——也就是说你可以在条件中引用循环体内刚刚声明的局部变量。

    4.3 数字型 for 语句

    格式:for var = exp1, exp2, exp3 do <循环体> end。变量 var 从 exp1 开始,每次增加 exp3,直到超过 exp2 为止。exp3 是可选的,默认为 1。如果想让循环无限进行,可以将 exp2 设为 math.huge。

    有几个细节值得注意:三个表达式只在循环开始前一次性求值,后续不会重新计算。控制变量 var 会被自动声明为 for 语句的局部变量,仅在循环体内可见,循环结束后就不可用了。

    4.4 泛型 for 语句

    泛型 for 通过迭代器遍历所有值,最典型的用法是:

    for i, v in ipairs(tableA) do
        print(v)
    end
    

    这里 i 是索引,v 是对应的元素值。ipairs 用于遍历数组部分(从索引 1 开始连续无空隙的序列),pairs 则用于遍历整个 table 的所有键值对,string.gmatch 可以迭代字符串中的单词。

    泛型 for 的一个经典应用是创建“逆向 table”——即将原 table 的键和值互换,生成一个新 table。

    4.5 break 和 return 语句

    这两个语句都用于跳出当前语句块:break 结束一层循环,return 结束一个函数的执行。如果需要在函数开头就提前返回(比如调试时),可以用一个显式的 do 块来包裹 return 语句,否则 return 必须放在函数的最外层或 do-end 块内。例如:

    function foo()
        do return end
        -- 后续代码不会执行
    end
    
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    上一篇: lua文件操作详解
    相关文章 更多
    编程语言的编程模型
    编程语言的编程模型

    编程模型涵盖面向过程的C语言、面向对象的Ruby、基于栈的PostScript、基于规则的Prolog、基于原型的Lua、函数式的Erlang/Haskell及混合模型的Scala/Clojure。类型系统区分强类型与弱类型、动态类型与静态类型,元编程允许运行时操作代码,提升表达力。

    lua 如何获取指定路径下的所有文件夹
    lua 如何获取指定路径下的所有文件夹

    Lua编程语言轻量级且小巧,可用io.popen执行系统命令获取指定路径下所有文件夹:在Windows系统下使用dir/b/s命令,在Unix系统下使用find-typef命令。然而官方更推荐使用lfs库进行递归遍历,通过lfs.dir和lfs.attributes函数筛选目录,此法避免系统命令依赖,代码简洁且跨平台效果更佳。

    lua调用C/C++的方法详解
    lua调用C/C++的方法详解

    Lua通过虚拟栈与C/C++交互,将C函数封装为接口供其调用。调用时,C从栈中获取参数并返回结果,参数传递与结果返回均通过栈操作完成,从而实现了Lua对C能力的高效、便捷调用,使得Lua能无缝利用C语言的高性能库。

    详解Lua中的元表和元方法
    详解Lua中的元表和元方法

    一、元表 元表是Lua中一个挺有意思的机制——它允许我们在一个值遇到未知操作时,给出自定义的行为。本质上,元表也是用table来承载的,所以熟悉了table,也就掌握了元表的基本用法。 不过得注意,元表只能针对一组预先定义好的操作集合做扩展,比面向对象中的类要受限得多。最典型的一点:元表不支持继承。

    如何使用Vim搭建Lua开发环境详解
    如何使用Vim搭建Lua开发环境详解

    基于SpaceVim搭建Lua开发环境,需先安装Neovim、Nerd字体及支持真色的终端,启用lang#lua模块后,即可获得全面的代码补全、语法检查、工程文件跳转、一键运行、代码格式化及交互式编程等高效开发功能,大幅提升编程效率与体验。

    Luvit像Node.js一样写Lua应用
    Luvit像Node.js一样写Lua应用

    先问个问题:如果你是一个Lua开发者,手头刚好有异步I/O的需求,你会怎么办?传统方案当然有,但要说最接近Node.js体验的,还得是Luvit。简单来说,它就是Lua界的Node.js——把Lua和libUV撮合在一起,再加上JIT加持,用项目自己的话说:Lua + libUV + JIT = p

    Lua流程控制语句if else的使用示例
    Lua流程控制语句if else的使用示例

    Lua的流程控制,if和if else是基础。和C语言很像,if语句支持嵌套,也能和循环配合——比如在循环体内根据条件决定是否跳出,这在日常开发中非常实用。 1、if语句 先看最基本的if语法结构: if(布尔表达式) then --[ 在布尔表达式为 true 时执行的语句 --] end 来看一

    Lua中pairs与ipairs的区别总结
    Lua中pairs与ipairs的区别总结

    最近在写一个流量转发的东西,用到了 nginx_lua_module 这个模块,需要根据 Header、Body 和 Cookie,按照流量比例把请求转发到其他地方。翻看前人留下的代码,发现循环遍历时,有时候用 pairs,有时候用 ipairs,风格并不统一,读起来让人有点困惑。 好在 Lua 官

    Lua游戏开发教程之时区问题详解
    Lua游戏开发教程之时区问题详解

    通过Lua的os.date("!*t")获取UTC时间,结合服务器时区差值,可将游戏内时间统一显示为服务器所在地时间。计算活动倒计时时,需考虑本地时区与服务器时区的差异,转换时间戳后得到准确剩余时间。正确处理时区问题能解决多语种发行中的显示同步难题。

    深入谈谈lua中神奇的table
    深入谈谈lua中神奇的table

    Lua中的table可作为字典、数组、环境、模块、对象和类使用。字典支持任意非nil键类型,遍历无序;数组索引从1开始,#对空洞处理需谨慎。table掌管全局环境_G和局部环境_ENV,模块本质为table。对象通过闭包实现私有成员,冒号语法糖简化self传递;类借助元表__index实现继承。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。