Lua学习记录__Lua中的坑

Lua中的坑——学习记录

  • 1.运算符
    • 1.1.逻辑运算符
      • 1.11. and or not 运算符
    • 1.2.其他运算符
      • 1.21. #运算符
        • 情况1
        • 情况2
        • 情况3
        • 情况4
    • 总结

1.运算符

1.1.逻辑运算符

1.11. and or not 运算符

逻辑运算符认为false和nil 都是假(flase)的,其他为真,0也是true
andor 的运算符返回结果不是 true 和false,而是和它的两个操作数相关

a and b 如果a为flase 返回 a,否则 返回b

a or b 如果 a为 true 返回a ,否则返回b

实用技巧 赋与初始值。如果a是flase 或者nil 就给它初始值b

  a = a or b

等价于

   if not a then
        a=b
   end

and的运算符优先级是比or高的

三元运算符 a ?b :c
在lua 里用 (a and b)or c 表示

lua 里运算符的优先级 从高到底
Lua学习记录__Lua中的坑_第1张图片

1.2.其他运算符

1.21. #运算符

#一元运算符,返回字符串或表的长度。 #“Hello” 返回 5 ,但是有个坑就是#在用于计算表中的长度时
有下面几种情况

情况1

元素都是给定了下标的时候
比如

local a={[1]=2,[2]=3,[3]=nil,[6]=5}

使用#时,运算机制是:

遇到了nil 就会继续去下个元素找,如果下个元素不是nil,则继续查找,如果是nil 返回结果了

比如:
local a={[1]=2,[2]=3,[3]=nil,[6]=5}

![输入](https://img-blog.csdnimg.cn/2019030122391699.png)

#a 会输出 2,(这里 存在两个是nil的情况,[4]的值为nil,此时它会则会返回了)
输出
而当 下标是连续的时候呢 (此时 只有一个下标为nil,会继续往下个查找)
输入输出
连续两个nil的情况,遇到两个nil 就返回了。
连续两个为nil的情况打印结果
情况1结论

元素都是给定了下标的时候,使用#运算符时,运算机制是:遇到了nil 就会继续去下个元素找,如果下个元素不是nil,则继续查找,如果是nil 返回结果了

情况2

如果元素中都没给定下标 lua内部编排

local b ={"a",nil,nil,nil,"ad"} 
print( #b )  --打印出5

输出
输入打印出3
这里运算方式就是,遇到了nil 就返回;

情况3

混着情况 上面1和2的结合
在这里插入图片描述
此时 b会覆盖掉[1]的位置
下标在前的情况打印出b
#c应该是2打印结果
其实不难理解 ,b把前面的[1]覆盖掉,就剩下b c 了 ;

混的情况下打印结果是2
结论 同2

情况4

table 里 存在不同域的元素时,#的计算

table 域的概念,

c[5]='e'  
c.a="a"  --这两个 是两不同的域 

一般像 c.a=‘a’ 这样的赋值,在table表里,存放的位置的靠后的。

 local x = {[1]='a',[3]='4',b='b',c='c',[5]='e'}
  print( #x )   --打印出1

这种也是属于所谓的混排情况,运算规则和情况3是一样的。

总结

  1. 元素都是给定了下标的时候: 使用#时,运算机制是:遇到了nil 就会继续去下个元素找,如果下个元素不是nil,则继续查找,如果是nil 返回结果了。

  2. 元素没有给定下标的时候或者混合的情况下 : 使用#时,运算机制是:遇到了nil 就不会继续去查找下个元素了,直接返回结果。

  3. 如下:

3.1还有一种就是在初始的时候没给下标,后面再去给nil,此时# 计算仍然是5
后面给nil输出结果仍然是5

而当一开始的时候就分配好了下标, 后面再去改nil的时候。就符合情况1 的运算规则了。
在这里插入图片描述在这里插入图片描述

Lua学习记录__Lua中的坑_第2张图片输出

#运算符 只会去计算 index域 里的 数量,而不会 去计算 其他域的数量,
比如 这里 #的运算 就把 键值对 a=1,b=2,c=3,d=4,e=5给省去了,而 pairs的运算 则把 nil给 省去了,

Lua学习记录__Lua中的坑_第3张图片
表里面 混排 真的挺危险的,

一般lua遇到nil 都会停止返回
if nil then
print(1)
end

 for k, v in pairs(a) do   -- 在循环中移除会造成内存泄漏
	if  a[4] then
		 table.remove(a,4)  --第一次 移除4号位置,后面位置往前顶 4号位置就存了5,第二再移除掉4号位置
	end
	print(v) 
	table.remove()##

原型:table.remove (tab_table [, pos])
解释:在表tab_table的pop位置删除元素,并且的必要时移动其他的元素(一般是将这个元素之后的元素向前移动),如果删除成功函数返回被删除的值,第二个参数pos,默认值为数组长度,也就是省略第二个参数时,会删除table的最后一个元素。

实际在上面的操作是不对的,如果pairs 里面进行删除操作的话,可能会造成内存泄漏,最好就是用一个表存下要删除的元素。做标记。

或者是从后往前删除,

for i = #test, 1, -1 do
    if remove[test[i]] then
        table.remove(test, i)
    end
end
dump(test)

顺便说说 值类型和引用类型,lua里函数,线程,表,都在创建的时候,就在内存上分配了一个地址在这里插入图片描述 ,引用类型不同与值类型,
变量存的是地址,在堆上。
而 值类型存的是值,在栈上。

关于对type的理解
type 类型 返回的 总是 字符串

你可能感兴趣的:(Lua,Lua,#运算符,Lua中的坑)