有什么理由让比较的形式仅为 <= 和 >=(不包括 =< 和 =>)?
What reasons are there for having comparisons be only of the form <= and >= (and not including =< and =>)?
在许多语言中,如Java和C/C++,总是以<=
和>=
的形式进行比较。例如,这里有一个工作示例程序:
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
// Get inputs
int input1 = s.nextInt();
int input2 = s.nextInt();
// compare them
if (input1 >= input2) {
System.out.println("Input 1 is greater than or equal to input 2");
} else {
System.out.println("Input 1 is less than input 2");
}
}
}
这会正确编译和运行。但是,如果我将一条比较线更改为:
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
// Get inputs
int input1 = s.nextInt();
int input2 = s.nextInt();
// compare them
if (input1 => input2) { // ------Changed this line------
System.out.println("Input 1 is greater than or equal to input 2");
} else {
System.out.println("Input 1 is less than input 2");
}
}
}
它在这里会产生编译器错误,就像在许多其他语言中一样。
这无疑是一个由语言语法产生的错误。但为什么语法会禁止这样的比较呢?从程序员的角度来看,在等号的哪一边使用比较运算符应该无关紧要。
因为这两种比较都将运算符放在等号的左侧,所以语法解析是线性进行的(从左到右,反之亦然)是有意义的。但为什么秩序会很重要?
因为=>
是有效的数学比较器,但它不是有效的语言标记。
编译器在编写时会做出很多妥协。不支持等号和大于号的每一个组合只是为了加快语言解析速度而做出的妥协之一。
---更新了上面提到的几个复杂度示例---
使用C++,从表面上看,这将是一个"简单的修复";其中解析器将为两个输入创建相同的"GreaterThanOrEqual"令牌;然而,当可以通过编写operator>=(...)
方法来覆盖"GreaterThanOrEqual"令牌的行为时,这并不像看上去那么容易。
是否应该提供两个operator>=(...)
和operator=>(...)
重写方法?是否需要某种机制使两者相同?如果你定义了一个而没有另一个,那么另一个是否应该"别名化"回定义的那个?人们可以很容易地看到,它将如何增加许多角落案件的复杂性。
发生这种情况有几个原因。(请注意,这完全基于观点和个人经验。)
这在很大程度上与常见做法和阅读代码的方便性有关。它还降低了编译器的复杂性,因为它们不必检查一堆不同的情况。(如果你加上特定的情况,它们还有更多的可能性需要考虑。)对于像C/C++这样的语言来说,这可能是个问题,因为它们有数百甚至数千个独特的编译器。(要想让它们都遵守标准可能已经够难的了,不必要的复杂性不太可能有帮助。)
很好奇别人对这个问题有什么看法。
编辑:自从我输入这个答案以来,其他人已经评论过了,它在其他语言中也被用来象征完全不同的操作。
简单地说,就是整个语言的可读性
想象一下,一个初学者尝试学习,并在所有课程中使用>=
。(因为这是标准。)
然后,他来到野外,被突然引入的=>
(看起来也有点像箭头)弄糊涂了
更糟糕的是,想象一个大型企业规模的项目,其中一半的程序员使用>=
,一半使用=>
,代码将是一个巨大的集群$SWEARWORD
。
这也是我们没有IF, WHEN, ISTRUE, EXECUTEASLONGAS
等的原因。我们只有IF
。
有些语言实际上可以定义自己的"运算符"。更准确地说,在Java、C/C++等语言中,这些运算符是"内置"的。然而,在像Smalltalk这样的语言中,没有运算符的概念。一切事物都是一个对象及其方法。因此,即使是像您这样的运算符也可以定义自己的"运算符"。话虽如此,我必须补充一点,尽管你可以自由地覆盖或添加这样的新运营商,但Smalltalk也非常不鼓励这样做。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中