Lua数据类型

lua入门的系列文章于2019年初诞生于陌陌公司内部的文档系统,目的是为部门内部的lua新人培训而做。2020年疫情期间想做些mln的推广,便转至公众号。佛系一段时间后觉得公众号受众面比较窄,遂转移至csdn,希望能帮助更多的人快速了解和掌握MLN这一跨平台技术。因都是本人所作,故打上了原创标签。


以下正文:

Lua是用C编写的一个小巧轻量级的脚本语言,所以我们通常也将Lua程序称为Lua脚本。lua有以下一些特性:

  • 轻量级
  • 易扩展
  • 支持面向过程、面向对象和函数式编程
  • 自动内存管理
  • 语言内置模式匹配、闭包
  • 函数可作为值传递
  • 支持模拟多线程【协程,非真正意义的多线程】

第一个Lua程序

但凡学个编程语言都逃不过hello world的命,我们还从hello world开始吧。如果你的设备是Mac,可以打开终端,输入lua并回车,就进入了lua的命令行模式,如下

Last login: Sun Feb  2 16:50:11 on ttys004
xxxx ~ $ lua
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> print("hello world")
hello world
>

在lua中我们通过print()方法输出想要的内容,入门完成了,下面切入正题。

Lua支持的数据类型

Lua支持的数据类型很少,共8种,分别是:nilbooleannumberstringfunctiontableuserdatathread

nil

是lua中的一个特殊的值,只有一个值nil,未定义的变量都是nil,可以将一个变量设置为nil来删除此变量的指向,下一个垃圾回收时将会释放这些资源(垃圾回收也称gc循环)

boolean

布尔值有true和false两个值,要注意的是在做条件判断时false和nil为否其他均为真

number

实数,Lua中没有整数和浮点数的概念,Lua可以处理任何长度的数而不用担心误差。

string

字符串,Lua是8位字节,所以字符串可以包含任何数值字符。你可以存储任意的二进制数据在一个字符串里。Lua中字符串是不可以修改的,你可以创建一个新的变量存放你要的字符串。

'hello world'    -- 通过单引号创建字符串
"hello world"    -- 通过双引号创建字符串,单引号双引号二者没什么区别

-- 通过[[...]]创建字符串,通常用来创建比较长的字符串
[[
hello 
world
]]

-- 将数组转成字符串
tostring(10)    -- "10"
-- 将字符串转成数字
tonumber("10")   -- 10
-- 通过 .. 进行字符串拼接(这种做发比较低效,正常开发中有更高效的方式,后面我们会讲到)
"aa-" .. "bb-" .. "cc-"    -- "aa-bb-cc-"
-- 字符串长度计算(两种方式)
local str = "hello"
#str    -- 5
string.len(str)  -- 5
特殊字符串: ( ) . % + - * ? [ ^ $

function

函数是第一类值(和其他变量相同),意味着函数可以存储在变量中,可以作为函数的参数,也可以作为函数的返回值。

-- 定义无参test函数
function test()
  print("hello world")
end
-- 调用test函数
test()  -- hello world

--------------------------------------------------

-- 定义带参testa函数
function testa(name)
  print("hello ", name, " !")
end
-- 调用testa函数
testa("北京")  -- hello 北京 !

--------------------------------------------------

-- 定义任意参数的testb函数
function testb(...)
  -- 用局部变量arg接收参数
  local arg = {...}
  -- 高效的字符串拼接方式,此处暂不需要理解table.concat()是啥
  local aimStr = table.concat(arg)
  print(aimStr)
end

-- 调用testb函数
testb("aa-", "bb-", "cc")    -- aa-bb-cc

--------------------------------------------------

-- 定义并使用匿名函数
function testc(num1, num2)
  -- 定义匿名函数
  function add(a, b)
    return a + b
  end

  -- 调用匿名函数
  add(num1, num2)
end

testc(10, 5)  -- 15

--------------------------------------------------

-- 函数作为参数传递
function testd(num1, num2, block)
  -- 如果block是个函数,则调用block
  if type(block) == "function" then
    block(num1 + num2)
  end
end

testd(5, 10, function(result)
  print(result)  -- 15
end)

table

table是lua中唯一的数据结构,也是极其强大的数据结构,与其他语言分为数组和字典两种数据结构不同,lua中table由数组和哈希两部分组成,通过table来实现数组和字典。
更神奇的是,我们可以通过table构建类与对象,并通过table提供的一些骚操作来实现面向对象。
【注:table中数组部分的索引从1开始】

-- 创建空表
local t = {}

-- 给表添加key-value
t["name"] = "小明"
t["age"] = 18
t.addr = "北京市朝阳区望京SOHO" 		-- 用.取值赋值更方便

-- 给表添加数组部分
t[1] = "aaa"
t[2] = "bbb"
t[3] = "ccc"

-- 创建key-value表
local tt = {
    name = "小明",
    age = 18,
    addr = "北京市朝阳区望京SOHO"
}

-- 创建list表
local ttt = {"aaa", "bbb", "ccc"}

-- 创建key-value和list并存的表
local tttt = {
    "aaa", 
    "bbb", 
    "ccc",
    name = "小明",
    age = 18,
    addr = "北京市朝阳区望京SOHO"
}

-- 表访问
print(t.name)     -- 小明
print(t["age"])   -- 18
local key = "addr"
print(t[key])    -- 北京市朝阳区望京SOHO

print(t[1])      -- aaa
local index = 2
print(t[index])  -- bbb
-- 输出表中的数组元素个数
print(#t)        -- 3

userdata

顾名思义就是用户数据类型,用户通过C或C++自定义的数据结构,使用MLN开发过程中,所有桥接原生的数据结构在lua中都是userdata类型的

thread

类似于线程,提供挂起和恢复等功能,可以方便的挂起或恢复一个操作。

在一个lua虚拟机中我们无法做到真正意义上的多线程,因为lua虚拟机是一个栈结构,所有的操作在虚拟机内部都是出栈和入栈操作。为了保证lua栈的线程安全,一般一个虚拟机只跑在固定的一个线程,在MLN中虚拟机是跑在主线程的,所有的异步操作由原生bridge完成,并在主线程将结果回调至虚拟机中。

随着大家对lua认识的进一步加深,慢慢会对这些有更深的了解,目前大可不必拘泥于这一点。

原文goto

你可能感兴趣的:(Lua)