我正在查看另一个开发者提交的项目差异,他们有很多代码使用!!<some BOOL value>
。实际上,这似乎是他们实现布尔类型getter和setter的标准模式。他们的代码实现方式如下:
- (BOOL) hasId {
return !!hasId_;
}
- (void) setHasId:(BOOL) value {
hasId_ = !!value;
}
我以前从未见过这种模式,想知道使用它是否有任何好处。这个双重否定有什么用吗?
我正在查看另一个开发者提交的项目差异,他们有很多代码使用!!<some BOOL value>
。实际上,这似乎是他们实现布尔类型getter和setter的标准模式。他们的代码实现方式如下:
- (BOOL) hasId {
return !!hasId_;
}
- (void) setHasId:(BOOL) value {
hasId_ = !!value;
}
我以前从未见过这种模式,想知道使用它是否有任何好处。这个双重否定有什么用吗?
双重布尔运算符只是确保返回的值为1或0。就是这样: )
obj.hasId = 42; if (obj.hasId == YES)
这样的代码失败。从技术上讲,YES
(目前)被映射为1,因此整数值不同。但从概念上讲,42和YES
都表示真布尔值。双重否定将42赋值折叠为YES
赋值。 - user557219if (obj.hasId == YES)
的比较时,这样做是否可以避免意外错误?虽然这样的比较本来就不太好的风格,对吧?编辑:算了,Bavarious已经提到了这一点。 - arothreturn _boolVar ? YES : NO;
- bbum!
是一个逻辑非运算符。因此,如果传递 setHasId:,例如 0x2,那么双重否定将存储为 0x1。
这相当于:
hasId_ = value ? 1 : 0;
在某些情况下,这是有用的,因为如果你这样做:
BOOL x = y & MY_FLAG;
如果设置了MY_FLAG
,可能会得到0,因为结果被截断为BOOL
(8位)的大小。这是意外的。出于同样的原因,有时人们更喜欢BOOL
是0或1(所以比特运算与预期相符)。通常这是不必要的。
在具有内置bool
类型的语言中,例如C(自C99起)和C++,将整数转换为bool
会自动执行此操作。
在某些情况下,这是更有意义的,例如当您返回BOOL
但不想使用if
语句时。
- (BOOL)isMyVarSet
{
return !!myVar;
}
myVar
,因为它不是一个BOOL
(这是一个非常牵强的例子 - 我无法从我的项目中挖出一个像样的例子)。if (!!myVar)
等同于:
if (myVar != nil)
基本上,我用它来验证SOMETHING的值。
if(myInstance)
,但是它重载了一元运算符!
,所以他们会使用if(!!myInstance)
。但就你的情况而言,我不知道。 - filipe