热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Lua中的三目运算符介绍

三目运算熟悉 C/C++ 的老司机都知道三目运算 a ? b : c,这种写法替换简单的条件判断语句可以在不增加阅读难度的情况下,使代码尽量保持简洁。int a, b, ret;//if-elseif

三目运算

熟悉 C/C++ 的老司机都知道三目运算 a ? b : c,这种写法替换简单的条件判断语句可以在不增加阅读难度的情况下,使代码尽量保持简洁。

int a, b, ret;
//if-else
if (a > b)
ret = a;
else
ret = b;
//三目运算符
ret = a > b ? a : b;

Lua 中的三目运算

Lua 原生的语义并没有实现三目运算,一般是通过逻辑运算符 and 和 or 来模拟三目运算符的。

Lua 中 and 和 or 都使用"短路求值(short_cur evaluation)",也就是说,它们只会在需要时才去评估第二个操作数。(《Lua程序设计》)

local a, b, ret;
ret = a > b and a or b

穷举所有可能性:

a > b 时:

a > b and a –> true
a or b –> a

a a > b and a –> false

a or b –> b

完美!

Lua 中的三目运算符陷阱

按照从特殊到一般的原则:


  • 三目运算的一般形式a ? b : c

    a = true,结果为b

    a = false,结果为c


  • 对应Lua中的a and b or c


    • b = true

      • a = true

        • a and b –> true

        • b or c –> b



      • a = false

        • a and b –> false

        • b or c –> c





    • b = false

      • a = true

        • a and b –> false

        • b or c –> c



      • a = false

        • a and b –> false

        • b or c –> c







可以看到当 b = false 时,Lua模拟的 a and b or c 始终返回 c 并不能还原三目运算符的原貌。

《Lua程序设计》也建议这种情况使用 if-else 来避免。

一般化的 a and b or c

那么有没有办法可以解决 b = false 失效的问题呢?

由此我联想到 C 语言有一道常规的考题:请使用宏定义写一个返回两个值中较小值的方法。

在校时第一次看到本题,第一反应如下:

#define MIN(A,B) A < B ? A : B

然而这种写法在很多嵌套的使用环境中都不能返回正确的结果。比如:2 * MIN(3, 4)展开为 2 * 3 #define MIN(A,B)((A)<(B)?(A):(B))

还有好奇心的同学可以参考:宏定义的正确写法,三目运算的宏定义

从这个示例中,我就在想如何能保证 a and b or c 中 b 为真或者 b 不产生歧义呢?


  1. and的运算优先级高于or,简单的改变运算顺序并没有用。

  2. 这时就想到了lua中万能的table,能不能把a,b,c都放到table中来改变b的存在呢?要注意{nil}也是一个为true的对象。

    a,b,c都替换为table:{a} and {b} or {c}。

  3. 三目运算中a是条件,结果是b或者c。其实a并不需要放入table中,否则{a}就始终为true了,失去了条件的意义。而{b} or

    {c}的结果也必然是一个table,该table只有一个元素。那么通过[1]即可访问。

  4. 综上所述,更一般化的Lua三目运算为:(a and {b} or {c})[1]


总结

诚然,要想知道Lua中三目运算的形式,只需通过搜索就可以找到想要的答案。上述的推理过程多少有点先知道答案,故意往答案上靠的嫌疑。不过我坚信证明一个问题,结论并不是最重要的,重要的是论证的过程。本文仅以我对Lua粗浅的认知来尝试还原一般化的Lua三目运算的推导过程,如有更好的推理过程,可以一起交流。


推荐阅读
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了在满足特定条件时如何在输入字段中使用默认值的方法和相应的代码。当输入字段填充100或更多的金额时,使用50作为默认值;当输入字段填充有-20或更多(负数)时,使用-10作为默认值。文章还提供了相关的JavaScript和Jquery代码,用于动态地根据条件使用默认值。 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • WPF之Binding初探
      初学wpf,经常被Binding搞晕,以下记录写Binding的基础。首先,盗用张图。这图形象的说明了Binding的机理。对于Binding,意思是数据绑定,基本用法是:1、 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 获取时间的函数js代码,js获取时区代码
    本文目录一览:1、js获取服务器时间(动态)2 ... [详细]
  • Ansibleplaybook roles安装redis实例(学习笔记二十九)
    1、相关redis参数:2、templatesredis.conf配置相关参数:daemonizeyespidfilevarrunredis_{{red ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了go接口相关的知识,希望对你有一定的参考价值。一、接口是什么接口提供了一种方式来 说明 对象的行为 ... [详细]
  • java布尔字段用is前缀_POJO类中布尔类型的变量都不要加is前缀详解
    前言对应阿里巴巴开发手册第一章的命名风格的第八条。【强制】POJO类中布尔类型的变量都不要加is前缀,否则部分框架解析会引起序列化错误。反例:定义为基本 ... [详细]
  • 3.5.2Calc的公式语法:使用Calc计算一个公式可用是任何能够被Emacs的calc包所识别的代数表达式.注意,在Calc中,的操作符优先级要比*低,因此ab*c会被解释为a ... [详细]
  • .webframe.core.struts2.WebFrameValidateExceptionInterceptor.doIntercept(WebFrameValidateExceptionInt
    .webframe.core.struts2.WebFrameValidateExceptionInterceptor.doIntercept(WebFrameValidateEx ... [详细]
author-avatar
斯高一耐
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有