lua学习之类型与值篇
类型与值
lua 是动态类型的语言
- 在语言中没有类型定义的语法
- 每个值都携带有它的类型信息
8种基础类型
- 用 type 可以返回这个值的类型的名称
- 将一个变量用于不同类型,通常会导致混乱的代码
- 但合理使用,如异常情况下返回 nil ,以区别正常情况下的其他类型的返回值
- 变量没有预定义的类型,任何变量都可以包含任何类型的值
print(type("Hello")) --string
print(type(666)) --number
a = print
print(type(a)) --function
a = 111
print(type(a)) --number
print(type(b)) --nil
print(type(string)) -- table 不太懂为什么
print(type(type(X))) -- string
- 最后一行将永远返回将永远返回 "string" , 而无关乎 X 这个值的内容。这是因为 type 函数总是返回一个字符串
nil (空)
- nil 类型只有一个值,表示空
- 主要功能是区别其他任何值
- 一个全局变量在它第一次赋值之前它的默认值就是 nil
- 将 nil 赋给一个全局变量等同于删除这个变量
- lua 将 nil 用于表示一种 "无效值"的情况,即没有任何有效值的情况
boolean (布尔)
- 布尔类型有两个可选值,
- 一个是 true,一个是 false
- true 表示真, false 表示假
- boolean 不是条件值的唯一表达方式
- 在 lua 中任何值都可以用来表示条件
- lua 将值 false , nil 视为假。将除此之外的其他值视为真
- lua 在条件测试中数字 0 和空字符串都视为真
number (数字)
- lua 中用于表示实数,即双精度浮点数
- lua 没有整数类型
- 可以重新编译 lua ,使用其他类型来表示数字
- 如 使用长整型 long 表示数字,或单精度浮点数 float 表示数字
- 书写一个数值常量,可以使用普通写法或科学计数法
科学计数法
- 在计算机中用 e 或 E 表示 ,表示10的几次方
- 可以简单理解为e 后面是多少就挪几个0
a = 3.2e2
print(a) --320
string (字符串)
- lua 中的字符串通常表示为一个字符序列
- lua 采用8位编码
- lua 字符串中的字符可以具有任何数值编码包括数值0
- 这种特性:可以让我们将任意进制(如二进制),存储到字符串中
- lua 中的字符串是不可变的值,不能像 C 语言那样可以直接修改一个字符串中的某个字符
- 而是应该根据修改要求建立一个新的字符串
修改子串
a = "one string"
b = string.gsub(a, "one", "another") -- 字符串替换函数
print(b) -- another string
print(a) -- one string
- lua 中的字符串和其他的 lua 对象如 table, function 一样都是自动内存管理机制所保存的对象
- 这意味着我们无需担心字符串的分配和释放
- 字符串可以是一个字母也可以是一本书的所有字符
- lua 可以高效处理长字符串,如100k ,1M容量的字符串
字面字符串
- 需要用一对匹配的单引号或者双引号来包裹
- 如果字符串本身包含两种引号中的一种,我们可以使用另一种引号来包裹
- 也可以使用 \ 来进行转义
a = 'Hello'
b = "World"
c = "I'm a student"
d = "I\'m a student'"
转义序列
- \a 响铃
- \b 退格
- \f 提供表格
- \n 换行
- \' 单引号
- \" 双引号
- \t 水平tab
- \v 垂直 tab
- \\ 反斜杠
- \r 回车
print("one line\nnext line\"in quotes\",'in quotes'")
--[[
one line
next line
"in quotes",'in quotes'
--]]
可以通过数值指定字符串中的字符
- 数值转义序列 \<XXX>
- <xxx>是一个至多三个十进制数字组成的序列
print('a' == '\97') -- true
- 用一对方括号 [[]] 可以包裹多行字符串
- lua 就不会解释其中的转义序列
- 如输入 html 代码
page = [[
<html>
<head>
<title>Lua Study</title>
</head>
<body>
<a href="http://www.lua.org">Lua 学习 </a>
</body>
</html>
]]
lua 提供了运行时数字和字符串的自动转换
print("10" + 1) --字符串10会被自动转换为数字10,结果打印为11
print("Hello" + 1) -- 会报错
字符串连接符 ..
- 可在多个字符串之间使用 .. 用以连接字符串
- 当在一个数字后输入它时,必须使用一个空格分割,不然 lua 会误解第一个点为小数点
print("A".."=".."B") -- A=B
print(10..24) -- 会报错
print(10 .. 24) -- 1024
长度操作符 #
- 可在字符串前放置 # 用以获取这个字符串的长度
print(#"Hello") -- 5
tonumber
- 将字符串显式地转换为数字
line = io.read() -- 读取一行
n = tonumber(line)
if n = nil then
error(line .. " is not a valid number")
else
print(n * 2)
end
tostring
- 将一个数字转换成字符串
- 也可将数字与一个空字符串用字符串连接符 .. 连接
a = 2333
print(tostring(2333) == "2333") -- true
print(a .. "" == "2333") -- true
table (表)
- lua 中的 table 类型实现了关联数组
- 关联数组就是具有特殊索引方式的数组
- 可以使用整数、字符串或其他类型的值(除了 nil)来做为索引
- table 没有固定大小,可以动态的添加元素到一个 table 中
- table 是 lua 中主要的也是仅有的数据结构机制
- 基于 table 可以简单、统一和高效的方式表示普通数组、符号表、集合、记录、队列和其他数据结构
- lua 通过 table 来表示模块、包和对象的
举例: io.read
io 模块中的 read 函数
使用字符串 read 作为 key 来索引 table io
在 lua 中 table 既不是值也不是变量,而是对象
可将 table 想象为一个动态分配的对象
程序仅持有对他们的一个引用(或指针)
lua 不会暗中产生 table 的副本,或者创建新的 table
在 lua 中不需要声明一个 table
- table 的创建是通过构造表达式来完成的
- {} 一对这样的大括号就称之为 table 的构造表达式
a = {} -- 创建了一个 Table 把它的引用存储到 a 这个变量里,那么 a 就是一个 table 类型的变量了
k = "x"
a[k] = 10 -- 新条目, key = x, value = 10 在 a 这个 table 添加了一个元素,这个 table 的索引是字符串索引,这个新生成的条目的值就是 10,它的索引是 x
a[20] = "great" -- 新条目, key = 20, value = "great"
print(a["x"]) -- 10
k = 20
print(a[k]) -- great
a["x"] = a["x"] + 1
print(a["x"]) -- 11
table 永远是匿名的
- 一个只有 table 的变量和 table 自身之间没有固定的关系
a = {}
a["x"] = 10
b = a -- b 与 a 引用了同样一个 table
print(b["x"]) -- 10
a = nil
print(a["x"]) --报错
print(b["x"]) --10 因为现在只有 b 在引用 table ,而 a 已经清除了对 table 的引用
b = nil -- 现在 a 和 b 都没有对 table 引用了
- 在 lua 中当一个程序在没有对 table 进行引用的时候,这个 table 就会被垃圾回收器给删除掉,并且释放它的内存
所有 table 都可以通过不同类型的索引来访问它的值
- 当需要添加新的元素的时候,table 会自动的增长
- 如果 table 中的某个值未被初始化的时候,那它就是 nil
- 可以通过给 table 中的某个元素赋值 nil 来删除它
- 因为 lua 将全局变量存储在一个普通的 table 种
-- for 循环 ,索引从1开始,与C或其他语言从0开始不同, do 里面的代码块是循环体
t = {}
for i = 1, 1000 do
t[i] = 2 * i -- 值是索引的两倍
end
print(t[8]) -- 16
t["x"] = 10
print(t["x"]) --10
print(t["y"]) -- nil
t["x"] = nil -- 删除了 table 中索引为 x 的元素
lua table 访问的两种写法(语法糖)
- a["name"]
- a.name
- 这两种写法是等效的
- a.name 的写法可能暗示了代码读者将 table 当做了一条记录使用
- 每个记录都有一组固定的预定义的键 key
- a["name"]的写法可能暗示了代码读者该 table 可以以任何字符串作为 key
- 而现在出于某些原因是需要访问某个特定的 key
a.x -- 表示为 a["x"] 以字符串 x 为索引 table
a[x] -- 以变量 x 的 值 为索引 table
a = {}
x = "y" -- x 已经被赋值为"y" 所以变量 x 的值为字符串 y ,索引 x 变量就是索引字符串 y
a[x] = 10
print(a.x) -- 索引为字符串 x --> nil
print(a["x"]) -- 索引为字符串 x --> nil
print(a[x]) -- 索引为变量 x --> 10
print("\n")
print(a.y) -- 索引为字符串 y --> 10
print(a["y"]) -- 索引为字符串 y --> 10
print(a[y]) -- 索引为变量 y --> nil
表示传统的数组或线性表
- 只需要 key 为整数即可
- 并不需要声明一个大小值,直接初始化元素就可以
- 数组通常以 1 作为索引的起始值
长度操作符 # 对于 table 的作用
- 用于返回一个数组或一个线性表的最后一个的索引值(或者称为大小)
t = {}
for i = 1, i = 666 do
t[i] = i * 2
end
print(#t) -- 666, 相当于这个 table 有 666 个元素(或者称这个 table 的大小为 666)
for i = 1, #t do
print(t[i])
end
print(t[#t]) -- 打印 table 最后一个值
t[#t] = nil -- 删除 table 的最后一个值
print(#t) -- 现在 table 的长度就是 665 个
t[#t + 1] = 8888 -- 给 table 再加一个元素
print(#t) -- 现在 table 的长度是 666 个
print(t[#t]) -- 现在 table 的最后一个元素就是 8888 了
数组的实际大小
- 对于所有未初始化的元素的索引结果都是 nil
- lua 将 nil 作为判断数组结尾的标志
- 当一个数组有空隙即中间含有 nil 时,长度操作符会认为这些 nil 元素就是结尾标记
- 注意:避免对含有空隙的使用长度操作符,可以使用 table.maxn,它返回一个 table 的最大正索引数
a = {}
a[10000] = 1
print(#a) -- 0
print(a[10000]) -- 1
print(table.maxn(a)) --> 10000
对于索引类型不明确时进行显式转换
- 使用 tonumber() 函数可以显式的转换为整数格式
i = 10
j = "10"
k = "+10"
t = {}
t[i] = "one value"
t[j] = "another value"
t[k] = "yet another value"
print(t[i]) -- one value
print(t[j]) -- another value
print(tonumber(t[k])) -- one value
print(tonumber[t[j]]) -- one value
print(t[tonumber(k)])
print(t[tonumber(j)])
函数
- lua 中函数是作为第一类值来看待的
- 函数可以存储在变量中
- 我们可以通过参数传递给其他函数,还可以作为其他函数的返回值
- 基于这种机制,当我们给一个函数添加新的功能的时候,程序可以重新定义这个函数
- 在运行一些不受信任的代码的时候,可先删除某些函数,从而创建一个安全的运行环境
- lua 既可以调用自身编写的函数,还可以调用 C 语言编写的函数
- lua 所有的标准库都是用 C 语言编写的
- 如:对字符串的操作
- 对 table 的操作
- 输入输出
- 操作系统的功能调用
- 数学函数
- 调试函数
- 应用程序也可以使用 C 语言来定义的其他函数
userdata (自定义类型)
- 可以将任意的 C 语言数据存储到 lua 变量中
- 没有太多的预定义操作
- 只能进行赋值和相等性测试
- 用于表示一种由应用程序或 C 语言库创建的新类型
- 如 标准的输入输出库(IO 库)就用 userdata 来表示文件
thread (线程)
- 后续学习
lua学习之类型与值篇的更多相关文章
- Lua学习之类型与值
Lua是一种动态语言,在语言中没有类型定义的语法. 在lua中有8中基本的类型: 1.nil(空) 2.boolean 3.number(数字) 4.string(字符串) 5.userdata(自定 ...
- Lua中的类型与值
[基础介绍] Lua是一种动态类型的语言.在语言中没有类型定义的语法,每个值都带有其自身的类型信息.在Lua中有8中基本类型,分别是: nil(空)类型 boolean(布尔)类型 number(数字 ...
- lua学习之深入函数第一篇
深入函数第一篇 函数是第一类值,具有特定的词法域 第一类值 第一类值的意思是函数与 lua 中的其他类型如数字,字符串具有相同的权力 函数可以存储到全局变量或局部变量变量,还可以存储到 table 中 ...
- lua学习之深入函数第二篇
深入函数 2 非全局的函数 函数是第一类值,函数可以存储到全局变量,局部变量,table 字段中 lua 函数库中的大部分函数存储到 table 字段中 Lib = {} Lib.foo = func ...
- Lua 学习笔记(二)语法、类型、值
首先Lua执行的每一段代码都称之为“程序块”,一个程序块也就是一连串的语句或命令,例如一个源码文件或一行代码.Lua语句之间并不需要分隔符,如代码中的换行就不起任何作用,当然为了养成编码习惯当两条或者 ...
- Lua学习高级篇
Lua学习高级篇 之前已经说了很多,我目前的观点还是那样,在嵌入式脚本中,Lua是最优秀.最高效的,如果您有不同的观点,欢迎指正并讨论,切勿吐槽.这个系列完全来自于<Programming in ...
- lua学习之复习汇总篇
第六日笔记 1. 基础概念 程序块 定义 在 lua 中任何一个源代码文件或在交互模式中输入的一行代码 程序块可以是任意大小的 程序块可以是一连串语句或一条命令 也可由函数定义构成,一般将函数定义写在 ...
- lua学习之table类型
关系表类型,这是一个很强大的类型.我们可以把这个类型看作是一个数组.只是 C语言的数组,只能用正整数来作索引: 在Lua中,你可以用任意类型的值来作数组的索引,但这个值不能是 nil.同样,在C语言中 ...
- php学习日志(5)-解决Windows Live Writer错误:WindowsLive.Writer.CoreServices.HttpRequestHelper的类型初始值设定发生异常
以前用Windows Live Writer写日志都好好的,前几天用写完日志,点击发布,突然弹出意外错误:“WindowsLive.Writer.CoreServices.HttpRequestHel ...
随机推荐
- HDU4507 吉哥系列故事——恨7不成妻 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意: 找到区间 \([L,R]\) 范围内所有满足如下条件的数的 平方和 : 不包含'7' ...
- 【5min+】 什么?原来C#还有这两个关键字
系列介绍 简介 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的. ...
- PHP 经典面试题集
这篇文章介绍的内容是关于PHP 经典面试题集 PHP 经典面试题集,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 结合我自己面试情况,面对的一些php面试题列举出来,基本上结合自己的看 ...
- 敏捷开发流程之Scrum:3个角色、5个会议、12原则
本文主要从Scrum的定义和目的.敏捷宣言.Scrum中的人员角色.Scrum开发流程.敏捷的12原则等几方面帮助大家理解Scrum敏捷开发的全过程. 一.Scrum的定义和目的 Scrum是一个用于 ...
- springboot-实现文件下载
一 前言 本文实现的文件下载是使用Apache 的 commons-fileupload 实现:在之前的springboot系列文件中已经讲述过如何实现多文件上传:这篇文件实现的文件下载功能主要是能在 ...
- Django之models字段属性
目录 常用字段 AutoField IntegerField CharField 自定义及使用char DateField DateTimeField 字段合集 字段参数 null unique db ...
- SpringBoot2 整合 Zookeeper组件,管理架构中服务协调
本文源码:GitHub·点这里 || GitEE·点这里 一.Zookeeper基础简介 1.概念简介 Zookeeper是一个Apache开源的分布式的应用,为系统架构提供协调服务.从设计模式角度来 ...
- 【Java基础总结】总结
总想着把学习的过程全都记录下来 以便某一时刻回头的时候,还能看见走过的路 对于基础来说,即使不回头看,也知道这条路是什么样子的 记录不记录,都无所谓 况且我不是专业的记录者,不记录比记录好 实在想不起 ...
- Maven 基础(一) | 使用 Maven 的正确姿势
一.什么是 Maven? Maven 是一个项目管理工具,它的本质是一个项目对象模型(POM),体现在配置中就是我们常见的 pom.xml 文件,而这个 pom 文件就是 Maven 的核心,它管理了 ...
- 7.JavaSE之类型转换
类型转换: 由于Java是强类型语言,所以要进行运算的时候,需要用到类型转换. 图中优先级从低到高,小数优先级大于整数. 运算中,不同类型的数据需要转换为同一类型,然后进行运算. 强制类型转换:(类型 ...