lua 函数条件与返回的区别是什么?
1.
function dum(t)
if t then return 1 end
return 0
end
2.
function dum(t)
if t then return 1 else return 0 end
end
上面两个函数在功能上是一样的,只是实现上有一些差别。
疑惑是
- 它们在语义上是否有差别?
- 它们在编译器中的实现方式是否相同?
- 在逻辑上,这两个函数是否完全一致?
希望能够能得到详解。谢谢!
真希波マリ
10 years ago
Answers
有一小点点区别,我这里先说一下查看Lua(我指的是其官方实现)汇编的方法吧。
用
luac -l src.lua
就可以在stdout上打印出
src.lua
生成的Lua VM字节码,并且是已经反汇编好了的。有了这个小技巧,我们就可以开始之后的讨论了。
我把你的这两个函数分别改名为
dum1()
和
dum2()
,顺带帮你写了个
dum3()
,程序内容和Lua反汇编结果如下:
~/ cat -n test.lua
1 function dum1(t)
2 if t then return 1 end
3 return 0
4 end
5
6 function dum2(t)
7 if t then return 1 else return 0 end
8 end
9
10 function dum3(t)
11 return t and 1 or 0
12 end
13
~/ luac -l test.lua
main <test.lua:0,0> (7 instructions at 0x7f85f1405a00)
0+ params, 2 slots, 1 upvalue, 0 locals, 3 constants, 3 functions
1 [4] CLOSURE 0 0 ; 0x7f85f1405c40
2 [1] SETTABUP 0 -1 0 ; _ENV "dum1"
3 [8] CLOSURE 0 1 ; 0x7f85f1405fe0
4 [6] SETTABUP 0 -2 0 ; _ENV "dum2"
5 [12] CLOSURE 0 2 ; 0x7f85f14060e0
6 [10] SETTABUP 0 -3 0 ; _ENV "dum3"
7 [12] RETURN 0 1
function <test.lua:1,4> (7 instructions at 0x7f85f1405c40)
1 param, 2 slots, 0 upvalues, 1 local, 2 constants, 0 functions
1 [2] TEST 0 0
2 [2] JMP 0 2 ; to 5
3 [2] LOADK 1 -1 ; 1
4 [2] RETURN 1 2
5 [3] LOADK 1 -2 ; 0
6 [3] RETURN 1 2
7 [4] RETURN 0 1
function <test.lua:6,8> (8 instructions at 0x7f85f1405fe0)
1 param, 2 slots, 0 upvalues, 1 local, 2 constants, 0 functions
1 [7] TEST 0 0
2 [7] JMP 0 3 ; to 6
3 [7] LOADK 1 -1 ; 1
4 [7] RETURN 1 2
5 [7] JMP 0 2 ; to 8
6 [7] LOADK 1 -2 ; 0
7 [7] RETURN 1 2
8 [8] RETURN 0 1
function <test.lua:10,12> (8 instructions at 0x7f85f14060e0)
1 param, 2 slots, 0 upvalues, 1 local, 2 constants, 0 functions
1 [11] TEST 0 0
2 [11] JMP 0 3 ; to 6
3 [11] LOADK 1 -1 ; 1
4 [11] TEST 1 1
5 [11] JMP 0 1 ; to 7
6 [11] LOADK 1 -2 ; 0
7 [11] RETURN 1 2
8 [12] RETURN 0 1
从实际的运行效果来说,这3个版本的
dum()
都是一样的(如果t不是false或者nil就返回1,否则返回0),但是实际运行起来略有一小点差别:
dum3()
会比前两个版本要多执行一个判断(因为Lua编译器没做什么优化,所以那个1还是要判断一下的)。
dum1()
和
dum2()
之间虽然后者比前者多编译出了一条JMP语句,但是由于这条JMP语句是在RETURN之后的,所以并不会影响程序实际的运行流程。
总结起来就是,这3个版本的
dum()
语义没有差别,运行的结果也一样,但是编译出来的语句略有差别:其中
dum1()
和
dum2()
运行流程一致,
dum3()
会多对常数1进行判断。
ruben
answered 10 years ago