我想检查一个值是否等于1。以下几行代码有什么不同吗
x == 1
1 == x
...就编译器执行而言?
在大多数语言中都是一样的。
人们经常做 1 == 评估值,因为 1 不是左值。这意味着您不会意外地完成作业。
示例:
if(x = 6)//bug, but no compiling error
{
}
相反,您可以强制编译错误而不是错误:
if(6 = x)//compiling error
{
}
现在,如果 x 不是 int 类型,并且您使用的是 C++ 之类的东西,那么用户可以创建一个运算符 ==(int) 覆盖,从而使这个问题具有新的含义。在这种情况下 6 == x 不会编译,但 x == 6 可以。
这取决于编程语言。
在 Ruby、Smalltalk、Self、Newspeak、Ioke 和许多其他单调度面向对象编程语言中,
a == b
实际上是消息发送。例如,在 Ruby 中,它相当于 a.==(b)
。这意味着,当你写 a == b
时,就会执行 ==
类中的方法 a
,而当你写 b == a
时,就会执行 b
类中的方法。所以,这显然是不是同一件事:
class A; def ==(other) false end; end
class B; def ==(other) true end; end
a, b = A.new, B.new
p a == b # => false
p b == a # => true
不可以,但是如果你不小心输入,后一种语法会给你一个编译器错误
if (1 = evaluatedValue)
请注意,如果你这样写,今天任何像样的编译器都会警告你
if (evaluatedValue = 1)
所以它主要与历史原因相关。
取决于语言。
在 Prolog 或 Erlang 中,
==
写作 =
,是统一而不是赋值(你断言值相等,而不是测试它们相等或强制它们相等),所以你如果左侧是常量,则可以将其用于断言,如here所述。
因此
X = 3
将统一变量 X
和值 3
,而 3 = X
将尝试将常量 3
与 X
的当前值统一,并且相当于命令式中的 assert(x==3)
语言。
都是一样的事情
一般来说,你是否使用并不重要, 评估值 == 1 OR 1 == 评估值。
使用您认为更容易阅读的内容。我更喜欢 if(Evaluated value == 1) 因为它对我来说更具可读性。
再次,我想引用java中字符串比较的一个众所周知的场景。 考虑一个字符串 str,您必须将其与另一个字符串“SomeString”进行比较。
str = getValueFromSomeRoutine();
现在在运行时,您不确定 str 是否为 NULL。所以为了避免异常,你会写
if(str!=NULL)
{
if(str.equals("SomeString")
{
//do stuff
}
}
为了避免外部空检查,你可以这样写
if ("SomeString".equals(str))
{
//do stuff
}
虽然这可读性较差,这又取决于上下文,但这可以为您节省额外的 if。
对于这个问题和类似的问题,我建议您通过编写一些代码,通过编译器运行它并查看发出的汇编器输出来自己找出答案。
例如,对于 GNU 编译器,您可以使用 -S 标志来执行此操作。对于 VS 编译器,最方便的途径是在调试器中运行测试程序,然后使用汇编器调试器视图。
有时,在 C++ 中,如果计算值是用户类型并且定义了运算符 ==,它们会执行不同的操作。糟糕。
但这很少是任何人会选择一种方法而不是另一种方法的原因:如果运算符 == 不是可交换/对称的,包括如果值的类型具有从 int 的转换,那么您可能会遇到一个可能需要修复的问题比四处打工。 Brian R. Bondy 和其他人的答案可能很能说明为什么有人在实践中担心它。
但事实仍然是,即使运算符 == 是可交换的,编译器也可能不会在每种情况下执行“完全相同”的操作。它(根据定义)会返回相同的结果,但它可能会以稍微不同的顺序执行操作,或者其他什么。
完全一样,但如果你不小心这样做了
if value = 1
if 1 = value
第一个可以工作,而第二个会产生错误。
evaluated value = 1
如果左侧的值是可分配的,这可能会很痛苦。例如,这是 C 语言中常见的“防御”模式。
在java中,你不能在布尔表达式中进行赋值,因此对于Java来说,相等操作数的写入顺序无关紧要;无论如何,编译器应该标记一个错误。