数据类型
「松饼人物编辑器:从入门到欧耶」系列教程(二)
上一讲的习题参考答案
1)
function ondraw()
print("哈哈")
end
print("呵呵")
2)
function ondraw()
if who == self then
print("哈哈")
else
print("嘿嘿嘿")
end
end
print("呵呵")
3) 把 TA 吊起来啪啪啪
变量
为了把人物技能做得明明白白, 学一些 Lua 的基础知识是免不了的。 即使不知道接下来要讲的知识点和人物技能有啥关系, 也要静下心来,慢慢理解 —— 扎实的基础对于理解人物技能而言乃是重中之重。
先看一个例子。 新建人物,名字随便填一个,尬入以下代码:
a = 42
print(a)
a = 233
print(a)
三狗测试,发现依次输出 42 和 233。
这个例子中,a
是一个「变量」。
一个变量代表一块内存空间 ——
我们可以向这个空间里写入数据,
也可以从这个空间里读取数据。
下面详细分解一下这四行代码的作用。
- 第一行的
a = 42
,就是向a
这个变量里写入 42 这个值。 第一行执行结束以后,42 这个值就乖乖躺在a
里了。 - 第二行的
print(a)
读取并输出了a
此时此刻的值 —— 也就是 42。 第二行执行以后,a
里的值还是 42 —— 读取并不会改变a
。 - 第三行的
a = 233
,向a
这个变量里写入了 233 这个值, 之前的 42 会被覆盖掉 —— 请想象 42 被赶出屋外,而屋子又被 233 占领的景象。 现在a
里装着的值已经是 233 了。 - 于是第四行的
print(a)
就会输出 233。
向一个变量里写入一个值,叫「赋值」。
表示赋值的符号是=
,也就是一个等号。
上面的例子中,我们先后通过=
将a
的值修改成了 42 和 233。
回忆一下,两个等号==
用来判断是否相等,别搞混了。
那么问题来了,在我们把 42 存进a
以前,a
是多少?
试一下不就得了:
print(a)
a = 42
print(a)
三狗测试,发现先后输出 nil
和 42。
也就是说,在我们往a
里放 42 以前,
a
是nil
。nil
又是个什么鬼?
这不明摆着吗,nil
就是啥也没有的意思。
我们没往a
里放东西,a
里当然啥也没有。
我们可以通过给一个变量赋nil
,以达到清空一个变量的目的:
print(a)
a = 42
print(a)
a = nil
print(a)
该代码依次输出 nil
, 42, nil
。
表达式
加减乘除就不用多解释了吧x
a = 3
b = 2
c = a + b * (b - a)
print(c)
每一行代码的作用如下:
a = 3
,把 3 存进a
。b = 2
,把 2 存进b
。c = a + b * (b - a)
,计算a + b * (b - a)
,将结果存入c
。print(c)
输出c
的值。
赋值号=
的右侧可以是个「表达式」。
像 3,2 这种数字都是表达式,
像 a
, b
这种变量也是表达式,
像 a + b * (b - a)
这种一长串式子也都是表达式。
表达式是个很强大的东西。 灵活运用表达式,可以让代码变得更简洁。 比如上面的那段代码,也可以这么写:
a = 3
b = 2
print(a + b * (b - a))
我们直接把计算c
的表达式写到了print
的参数上,
省掉了一行代码。
其实还可以更进一步,把a
和b
也省掉:
print(3 + 2 * (2 - 3))
但这么写有一个缺点:如果你想把a
改成 4,怎么办?
只能屁巅屁巅地把所有的 3 都一个个改成 4,不但累,还有可能手滑误改。
但之前的代码就不一样了,直接把a = 3
改成a = 4
就行了。
写代码的时候要有「防累」和「防手滑」意识。 写下一行代码时,不光要考虑到这行代码是否满足眼下的需要, 更要考虑到将来是否可能会累死、是否可能会手滑。 人不能自己给自己挖坑。
上面的例子中的表达式里用到了括号。 有些时候,即使是不影响计算的优先级,也会多加几个括号 —— 主要是为了确保万无一失,同时也是为了改起来更方便。
变量名
上面的例子里,我们用了a
, b
, c
, d
这样的简单变量名。
其实变量名还可以很长:
wwww = 2333
emmmmmmmmmmmmmmmmmmmmmmm = 66666
名字很重要。
变量名起得好,别人一看就能明白这段代码的意思。
反过来,如果a
, b
, c
这种意义不明的名字满天飞,
是会被人吊起来啪啪啪的。
Lua 是区分大小写的:
emmm = 2333
Emmm = 66666
print(emmm)
print(Emmm)
上面的代码输出 2333 和 66666,可见emmm
和Emmm
是两个不同的变量。
变量名可以由字母、数字、和下划线组成,同时不能以数字开头。 虽然可以用大写,但习惯上(至少在 Lua 标准库中)一般只用小写变量名。
在三次元中,你可以给你家的狗起名为if
,
但在 Lua 中这是非法的 —— if
这个词已经被 Lua 保留了,
它是用来写if
语句的,不能再用if
给变量命名。
像if
这种不能用来给变量命名的词,叫「关键字」。
在 Lua 中,以下单词都是关键字:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while
使用关键字命名变量是非法的。
除此之外,有些变量名虽然合法,但不道德 ——
这就好比三次元中,给小孩起一些奇怪的名字,会影响他们的人生一样。
Lua 中有两种不道德的命名:
一是_G
, _ENV
这种「下划线开头 + 大写字母」的变量名,
二是__index
, __add
这种「双下划线开头」的变量名。
这些名字通常具有一些特殊意义,拿它们给普通的变量命名是作死行为,
鬼才知道会有什么后果。
类型
世上的一切事物都是有类型的。 对于不同类型的事物,我们所能做的事情也不同。
比如,苹果、麻婆豆腐、炸鸡都是「食物」类型的。食物可以吃。 而桌子、椅子、床都是「家具」类型的。家具不能吃,但可以踢。 至于游泳、上吊、捉奸则是属于「行动」类型的。 行动不能吃,不能踢,但可以做。
三次元尚如此,况 Lua 乎? 在 Lua 中,数据一共有 7 种类型:
- number
- string
- boolean
- table
- function
- userdata
- nil
类型 number
number 就是数字,数字可以用来加减乘除,就好比食物可以吃一样。
我们已经用过好多次数字了,不再赘述:
a = 23333
b = a + 777
类型 string
string 就是字符串。所谓字符串,就是一些文字组成的串。 在 Lua 中,可通过双引号表示字符串:
a = "hahaha"
print(a)
三狗测试,见这段代码输出「hahaha」。
我们可以通过..
(两个点)拼接两个字符串:
a = "hahaha"
b = "hehehe"
c = a .. b
print(c)
三狗测试,见这段代码输出「hahahahehehe」。
字符串可以拼接,但不能加减乘除。 这就好比家具可以踢,但不能吃一样。
a = "haha"
b = "hehe"
c = a + b
print(c)
三狗测试,见这段代码报错。
其实有些家具也是可以吃的,比如用麻婆豆腐做成的床就可以吃:
a = "12"
b = "34"
c = a + b
print(c)
上面的代码输出 46。虽然可以正常运行, 但没事别老写这种作死的代码 —— 整天把床当成麻婆豆腐吃,迟早要完。 数字就是数字,字符串就是字符串。
类型 boolean
boolean 只有两种值:true
与false
,即真与假。
具体细节以后会详细讲。
a = true
b = false
之前用过的==
的计算结果就是 boolean 类型的:
print(1 + 1 == 2)
print(1 + 1 == 3)
测试可知上面的代码先后输出true
和false
。
类型 table
table 是一种万能的东西, 可以用来做各种数据结构。 至于「数据结构」是个什么鬼,以后再说。
a = { 1, 2, 3, 4, 5 }
b = { width = 200, name = "doge" }
print(a[3])
print(b.name)
类型 function
function 就是函数类型。 这个也以后再详细说吧x
square = function(n)
return n * n
end
a = square(3)
print(a)
类型 userdata
Lua 这门语言通常用来去「扩展」其它应用。 userdata 就是那些被扩展的应用为 Lua 添加的新类型。 例如,麻将牌、牌山、牌河这此由松饼为 Lua 添加的类型都属于 userdata。
t = T34.new("2m")
类型 nil
之前说过,nil
就是什么都没有的意思。
只有nil
这个值是 nil 类型的。
我们可以通过== nil
来判断一个变量是否为nil
。
print(a == nil)
a = 2333
print(a == nil)
测试可知,上面的代码先后输出true
和false
。
练习题
1) 列举两种 Lua 编程中的作死行为
2) 举出一个合法变量名和一个非法变量名的例子
3) 以下代码执行后,a
, b
, c
, d
分别是什么类型?
a = 777
b = "777"
c = d
d = a == b
4) (附加题)上一题的代码执行后,d
的值是什么?
下一讲:函数