我想检查一个值是否等于1。以下代码行有什么区别
评估值 == 1
1 == 评估值
就编译器执行而言
在大多数语言中都是一样的。
人们经常做 1 == 评估值,因为 1 不是左值。这意味着你不能不小心做作业。
例子:
if(x = 6)//bug, but no compiling error
{
}
相反,您可以强制编译错误而不是错误:
if(6 = x)//compiling error
{
}
现在,如果 x 不是 int 类型,并且您使用的是 C++ 之类的东西,那么用户可能已经创建了一个 operator==(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 或 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++ 中,如果评估的值是用户类型并且定义了 operator==,它们会做不同的事情。很糟糕。
但这很少是任何人选择一种方式而不是另一种方式的原因:如果 operator== 不是可交换/对称的,包括如果值的类型具有从 int 的转换,那么你有一个可能想要修复而不是修复的问题工作。Brian R. Bondy 和其他人的回答可能是人们在实践中担心它的原因。
但事实仍然是,即使 operator== 是可交换的,编译器在每种情况下也可能不会做完全相同的事情。它将(根据定义)返回相同的结果,但它可能会以稍微不同的顺序或其他方式做事。
if value == 1
if 1 == value
完全一样,但如果你不小心做了
if value = 1
if 1 = value
第一个将起作用,而第二个将产生错误。
他们是一样的。有些人喜欢把 1 放在第一位,以免不小心掉入打字的陷阱
evaluated value = 1
如果左侧的值是可分配的,这可能会很痛苦。例如,这是 C 语言中常见的“防御”模式。
在 C 语言中,通常将常量或幻数放在首位,这样如果您忘记了相等检查 (==) 的“=”之一,那么编译器不会将其解释为赋值。
在 Java 中,您不能在布尔表达式中进行赋值,因此对于 Java,相等操作数的写入顺序无关紧要;无论如何,编译器都应该标记一个错误。