【发布时间】:2016-01-12 05:18:32
【问题描述】:
我一直不明白为什么我们使用这样的语法:
if (a == b || a == c)
什么时候可以简化成这样:
if (a == b || c)
这是编译器的问题还是什么?我们真的可以不考虑这样的一串代码并让它工作吗?
【问题讨论】:
标签: logic programming-languages language-design
我一直不明白为什么我们使用这样的语法:
if (a == b || a == c)
什么时候可以简化成这样:
if (a == b || c)
这是编译器的问题还是什么?我们真的可以不考虑这样的一串代码并让它工作吗?
【问题讨论】:
标签: logic programming-languages language-design
没有任何技术限制使得不可能(甚至太难)实现一种将a == b || c 视为a == b || a == c 的快捷方式的语言。问题是,几乎(?)不可能只在预期的情况下制定规则。
例如考虑表达式result == null || fileIsClosed,其中fileIsClosed 是一个布尔值。当然,程序员不会期望这会被视为result == null || result == fileIsClosed。您可以提出其他规则,例如“仅当|| 的右操作数不是布尔值时才应用替换”,但是如果您执行booleanResult == possibleResult1 || possibleResult2,则替换也不起作用。事实上,关于这个例子,唯一能告诉我们程序员是否打算进行替换的是变量的名称。显然,编译器无法从变量名中推断出含义,因此不可能在每种情况下都按照用户的意愿去做,制定没有例外的简单规则(如“expr1 || expr2 为真,如果至少有一个 expr1 和expr2 是真的") 更可取。
总而言之:我们不希望在所有情况下都发生替换,并且不可能完全准确地推断在哪些情况下替换是有意义的。由于代码应该很容易推理,因此根据 90% 的程序员不知道或不理解的规则来实现可能会或可能不会应用替换的系统在某些情况下会导致令人困惑的行为,因此不是一个好主意.
【讨论】:
if (a == (b || c)) 更清楚地表明,目的是将“a”值与 n 个其他值进行比较。
all(o == a for o in [b, c]) 或者对于相等比较的特殊情况a in [b, c]。
a、b 和c 是布尔值时,替换将有类似的问题。毕竟,如果您必须编写bool tmp = b || c; if(a == tmp) 才能真正获得if(a == (b || c)) 的“真实”语义,那会很奇怪。虽然不可否认,我想不出一个实际的例子,你实际上需要检查一个布尔值是否等于另外两个布尔值的析取。
部分答案是:if (a == b || c) 在没有上下文或不知道此表达式背后的含义的情况下无法解释。
考虑以下情况:
如果c 本身是一个布尔表达式或布尔值怎么办?然后可以将其解释为:
if (a has the value of b OR c is true)
if (a has the value of b OR c)
现在人类编码这些行的意图是什么? ... *思考。当要求编译器生成要在机器上执行的目标代码时(正如开发人员所期望的那样),我们并不完全知道,也不知道编译器。
或更彻底:编译器可以(而且不应该)像人类有时那样猜测。
【讨论】:
你可以,你只是使用了错误的编程语言:)
以Icon 为例,您可以写成a = (b | c)。工作方式是| 真正连接序列,=(相等)过滤它们(其中 false 是没有结果,而 true 是一些结果)。它通过回溯实现这一点。
你可以做更疯狂的事情,比如write ((0 to 4) > 1) * 3 会打印出 6 9 12。
【讨论】:
你已经知道你写的字符串会有不同的含义。然而,一些语言提供了扩展来改变操作符的行为。如果您想定义自己的自定义操作,可以使用它。
【讨论】: