为什么Java和C#没有到布尔值的隐式转换?
自从我开始使用Java以来,它不支持从数值类型到布尔值的隐式转换,这让我非常恼火,因此您不能执行以下操作:为什么Java和C#没有到布尔值的隐式转换?,c#,java,boolean,type-conversion,C#,Java,Boolean,Type Conversion,自从我开始使用Java以来,它不支持从数值类型到布尔值的隐式转换,这让我非常恼火,因此您不能执行以下操作: if (flags & 0x80) { ... } 相反,你必须经历这种疯狂: if ((flags & 0x80) != 0) { ... } null和objects也是如此。我所知道的所有其他类似C的语言(包括JavaScript)都允许这样做,所以我认为Java只是个傻瓜,但我刚刚发现C#是一样的(至少对于数字来说,不知道null/objects): 微软故意
if (flags & 0x80) { ... }
相反,你必须经历这种疯狂:
if ((flags & 0x80) != 0) { ... }
null和objects也是如此。我所知道的所有其他类似C的语言(包括JavaScript)都允许这样做,所以我认为Java只是个傻瓜,但我刚刚发现C#是一样的(至少对于数字来说,不知道null/objects):
微软故意改变它,从C++,为什么?很明显我遗漏了什么。为什么改变(我认为是)是世界上最自然的事情,让打字变得更长?它到底出了什么问题?Java和C都放弃了对布尔值的隐式转换,以减少程序员出错的机会
例如,许多程序员会意外地编写:
if( x = 5 ) { ... }
而不是:
if( x == 5 ) { ... }
这当然会导致完全不同的行为,因为第一个语句执行赋值(这将始终导致true),而第二个语句执行比较。过去,开发人员有时会以相反的方式编写此类任务,以避免陷阱,因为:
if( 5 = x ) { ... } // doesn't compile.
现在,在C#中,您仍然可以为自己的类型创建到bool
的隐式转换运算符,尽管这是不可取的,因为大多数开发人员并不期望它:
public class MyValue
{
public int Value { get; set; }
public static implicit operator bool( MyValue mb )
{
return mb.Value != 0;
}
}
MyValue x = new MyValue() { Value = 10; }
if( x ) { ... } // perfectly legal, compiler applies implicit conversion
为了清楚起见。它犯下以下错误简直是违法的:
int x = ...;
if (x = 0) // in C: assign 0 to x and always evaluate to false
.... // never executed
注意:大多数现代C/C++编译器会对这个简单的模式给出警告(但不是错误),但是可能有很多变化。它可能会悄悄地向你袭来。也许他们觉得更显式更符合强类型语言。即使是最有经验的程序员也会遇到隐式转换为布尔值的问题。我个人很欣赏这个小功能。将任何int值(如(flags&0x80))隐式转换为布尔值意味着语言定义的从int值到布尔值的映射。C做到了这一点,并造成了大量的混乱和大量的程序员错误。没有很好的理由说明为什么零整数值总是意味着真(或假),也有很多很好的理由说明为什么您可能希望将决定权留给程序员。由于这些原因,大多数现代语言都放弃了对布尔值的隐式转换
如果你每次做一个小测试时多输入七个字符就构成了“精神错乱”,那么你可能从事了错误的职业。如果您非常频繁地在int中执行位测试,您可能需要考虑是否过早地优化以节省内存。某些编程语言根本不执行自动强制。例如,一个整数只能与另一个整数进行比较;赋值给非整数变量会导致错误。这就是强类型语言的特点 Java执行任何强制操作对您来说都是一种方便,并且打破了强类型模型 将整个整数范围——或者更大范围的浮点值——映射到两个布尔值上,在“真”和“假”的任意赋值上充满了分歧
- 什么值映射到false和true?如果是C,则只有零映射为false,其他所有值都为true。如果您是bash shell,则相反
- 负值应该如何映射
当您尝试将double自动转换为整数时,Java会将其标记为“精度损失”错误。通过类比,将数字转换为布尔值也会导致精度损失。相反,Java选择不在语法上支持它。您已经将它向后推了。
实际上,C不支持
boolean
,因此if
(以及任何其他条件语句)实际上需要int
值,而不是boolean
。然后0
的int值被视为false,任何其他值被视为true
事实上,有些人觉得这有点模棱两可,因为正如其他人所指出的,这种行为会导致许多错误。因此,Java设计人员选择了在条件语句中只支持boolean
类型。当微软决定实现MS Java(又名C#)时,他们借用了这个设计原则
如果你不喜欢它,你可以用多种语言编写程序,而不受此限制。这不是疯狂,只是你不习惯。
If(status=code\u RED)launch\u nuclear\u飞弹()代码>真正的问题是,为什么像C这样的语言允许隐式转换为布尔:)这是一个特性,而不是一个bug。为什么隐式转换应该是默认的呢flags&0x80
与true
和false
的逻辑概念无关,因为在某些系统上true
恰好表示为非零数。这与指出字符串“0”
也应表示false
一样错误<代码>(标志和0x80)!=另一方面,现在这是一个有意义的布尔表达式!理论上,在C#中,x
类型可能实现从int
到bool
的隐式转换运算符,在这种情况下,这将在C#中编译。如果您确认x
是内置的数字类型(如int
),那么您的示例是绝对正确的。@LBushkin,您是对的,我将添加它。但是,假设自定义转换在这里有点牵强。许多卑鄙的C提交都在代码的某个地方隐藏了这个小栗子。这种“疯狂”就是为什么我们有++
操作符,它过去用于优化INCR指令,但现在只是作为一种键入快捷方式。我同意。到布尔值的隐式转换可能很有用,但声明某些任意值为false,而另一些同样任意的值为true并不是w