【1】lua语言中完整的三目运算符

完整三目运算符形式:(a and {b} or {c})[1]

【2】分析原因

大部分C或C++程序员经常会用到三目运算符(三元运算符),形如 a ? b : c; 的逻辑,即a为真,表达式值为b,否则表达式值为c。

这样的逻辑在写lua的时候也常常需要用到,于是有人发明了形如 a and b or c 这种写法,下面来先来分析一下这个表达式的问题:

Lua语言中的逻辑操作符有and、or和not。所有的逻辑操作符将 false 或 nil 视为假,而将除此之外的任何东西视为真。

对于操作符and来说,若它的第一个操作数为假,就返回第一个操作数;否则返回第二个操作数。(即a与b,见假则假)

对于操作符or来说,如果它的第一个操作数为真,就返回第一个操作数;否则返回第二个操作数。(即a或b,见真则真)

lua的经典书籍《Lua程序设计》中还有一段写到:and和or都是用“短路求值”,也就是说,它们只会在需要时才会去判断第二个操作数。

短路求值可以确保像(type(result) == "table" and result["msg"] == "OK")这样的表达式不会导致运行错误。

“短路求值”可以保证在result不是table的情况,不会判断result["msg"] == "OK"的值而直接返回false。

另外书中还提到“a and b or c”是一种类似于C语言中的表达式 a ? b : c 的习惯写法,可是并未指出其中的问题。

但是,译者在此注明了观点,他指出如果要想让a and b or c等价于a ? b : c,前提是b表达式必须为真,也就是说b不能等于false或者nil。

最后译者给出了建议,那就是在无法确认b为真的情况下,最常用的办法还是使用正常的if-else语句。

说到这里可能有些人开始反迷糊,为什么b表达式的值必须为真呢?

这个时候你可以写个例子尝试一下,如果b == false,那么无论a的表达式为真或者假,整体都会返回c的值。

那么怎样才能保证b的值一直为真呢?实际的程序逻辑中是允许b为false或者nil的!

写到这里也是为了记录一下,好奇之余从其他人学到的技巧:

b表达式的外边包装一层table,写成{b}的形式,返回时再写成{b}[1]的形式就可以,那么整体的表达式就变成:(a and {b} or {c})[1]

这样就满足第二个表达式恒为真的前提,今后你可以在lua中愉快地写三目运算符了!

【3】示例

(3.1)示例程序1

 local var_false = false

 local var_true = true

 -- 场景1:
local a =
local b =
print('a > b and a or b : ' .. (a > b and a or b))
print('a > b and false or b : ' .. (a > b and var_false or b))
--print('a > b and true or b : ' .. (a > b and var_true or b)) 语法错误
print('(a > b and {a} or {b})[1] : ' .. (a > b and {a} or {b})[])
print() -- 场景2:
a =
b =
print('a > b and a or b : ' .. (a > b and a or b))
print('a > b and false or b : ' .. (a > b and var_false or b))
print('a > b and true or b : ' .. (a > b and var_true or b))
print('(a > b and {a} or {b})[1] : ' .. (a > b and {a} or {b})[])
print() -- 场景3:
a =
b =
print('a > b and a or b : ' .. (a > b and a or b))
print('a > b and false or b : ' .. (a > b and var_false or b))
print('a > b and true or b : ' .. (a > b and var_true or b))
print('(a > b and {a} or {b})[1] : ' .. (a > b and {a} or {b})[])
print() -- 运行结果:
--[[
a > b and a or b : 2
a > b and false or b : 1
(a > b and {a} or {b})[1] : 2 a > b and a or b : 3
a > b and false or b : 3
a > b and true or b : 3
(a > b and {a} or {b})[1] : 3 a > b and a or b : 5
a > b and false or b : 5
a > b and true or b : 5
(a > b and {a} or {b})[1] : 5
--]]

(3.2)示例程序2

 local a = true
local b = false
-- 场景1:
print((a and {"true"})[])
-- 场景2:语法错误
--print((b and {"true"})[1]) error: attempt to index a boolean value
-- 场景3:
print("a value : " .. (a and {"true"} or {"false"})[])
print("b value : " .. (b and {"true"} or {"false"})[]) --[[ 运行结果:
true
a value : true
b value : false
--]]

Good Good Study Day Day Up

顺序 选择 循环 总结

lua语言三目运算符的更多相关文章

  1. 用VC编译lua源码,生成lua语言的解释器和编译器

    用VC编译lua源码,生成lua语言的解释器和编译器 1.去网址下载源码 http://www.lua.org/download.html 2.装一个VC++,我用的是VC6.0 3.接下来我们开始编 ...

  2. 51CTO专访淘宝清无:漫谈Nginx服务器与Lua语言

    http://os.51cto.com/art/201112/307610.htm 说到Web服务器,也许你第一时间会想到Apache,也许你会想到Nginx.虽然说Apache依然是Web服务器的老 ...

  3. 【quick-cocos2d-x】Lua 语言基础

    版权声明:本文为博主原创文章,转载请注明出处. 使用quick-x开发游戏有两年时间了,quick-x是cocos2d-Lua的一个豪华升级版的框架,使用Lua编程.相比于C++,lua的开发确实快速 ...

  4. lua语言入门之Sublime Text设置lua的Build System

    转自: http://blog.csdn.net/wangbin_jxust/article/details/8911956 最近开始学习LUA语言,使用Sublime Text作为编辑器,不得不说, ...

  5. 编译并使用Lua语言

    Lua是一个小巧的脚本语言,该语言设计的目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. 可扩展性.Lua的扩展性非常卓越,可以通过Lua代码或C代码扩展,很多功能可以通过外部库来扩 ...

  6. Lua语言在Wireshark中使用(转)

    1.       检查Wireshark的版本是否支持Lua 打开Wireshark,点击“HelpàAbout Wireshark”菜单,查看弹出的对话框,如果有“with Lua 5.1”表示支持 ...

  7. Unity进阶----Lua语言知识点(2018/11/08)

    国内开发: 敏捷开发: 集中精力加班堆出来第一个版本 基本没啥大的bug 国外开发: 1).需求分析: 2).讨论 3).分模块 4).框架 5).画UML图(类图class function)(e- ...

  8. lua语言自学知识点----Lua与.Net相互调用

    知识点: LuaInterface作用是用来完成Lua与C#的相互调用. LuaInterface核心库:1.luainterface.dll 用于C#读取lua(放在bin目录同级) 2.luane ...

  9. lua 语言笔记

    Lua语言基础汇总(1) -- 类型与值 基础介绍 Lua是一种动态类型的语言.在语言中没有类型定义的语法,每个值都带有其自身的类型信息.在Lua中有8种基本类型,分别是: nil(空)类型 bool ...

随机推荐

  1. Scala学习笔记(七):Rational、隐式转换、偏函数、闭包、重复参数及柯里化

    class Rational(n: Int, d: Int) { require(d != 0) private val g: Int = gcd(n, d) val number: Int = n ...

  2. Quartz.net设置任务中同时最多运行一个实例 [DisallowConcurrentExecution]

    Quartz定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行, 如果定时任执行太长,会长时间占用资源,导致其它任务堵塞. 比如Job设置1分钟跑一次,每次获取50条短信发 ...

  3. NuGet Packages are missing,This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.

    错误内容 This project references NuGet package(s) that are missing on this computer. Use NuGet Package R ...

  4. 阿里云php-7.2.12 安装

    安装依赖 yum -y install libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml ...

  5. 【QT】文件读写操作

    读取输出: QFile file("D:/Englishpath/QTprojects/1.dat"); if(!file.open(QIODevice::ReadOnly)) { ...

  6. 【2019年04月10日】股票的滚动市盈率PE最低排名

    仅根据最新的市盈率计算公式进行排名,无法对未来的业绩做出预测. 新钢股份(SH600782) - 滚动市盈率PE:3.87 - 滚动市净率PB:1.29 - 滚动年化股息收益率:1.31% - 钢铁 ...

  7. 告别GOPATH,快速使用 go mod(Golang包管理工具)

    https://studygolang.com/articles/17508?fr=sidebar 文中的wserver为module名,route为本地的包名,go.mod所在的目录名不一定非要和m ...

  8. Linux下">/dev/null 2>&1 "相关知识说明

    在学习Linux的过程中,常会看到一些终端命令或者程序中有">/dev/null 2>&1"出现,由于已经遇到了好几次了,为了理解清楚,不妨花点时间百度或者go ...

  9. windows 10 更新补丁包

    http://www.catalog.update.microsoft.com/Search.aspx?q=windows%2010%20prohttp://www.catalog.update.mi ...

  10. Qt编写自定义控件4-旋转仪表盘

    前言 旋转仪表盘,一般用在需要触摸调节设置值的场景中,其实Qt本身就提供了QDial控件具有类似的功能,本控件最大的难点不在于绘制刻度和指针等,而在于自动计算当前用户按下处的坐标转换为当前值,这个功能 ...