Answers:
如果您将BOOL
变量用作布尔值,则没有实际区别。C根据布尔表达式的计算结果是否为0或0来处理它们。
if(someVar ) { ... }
if(!someVar) { ... }
与...相同
if(someVar!=0) { ... }
if(someVar==0) { ... }
这就是为什么您可以将任何原始类型或表达式评估为布尔测试(包括指针)的原因。请注意,您应该做前者,而不是后者。
请注意,如果您将钝值分配给所谓的变量并测试特定值,则有所不同BOOL
,因此请始终将其用作布尔值,并仅从其#define
值中分配它们。
重要的是,永远不要使用字符比较来测试布尔值-这是冒险的,因为someVar
可能会被分配一个非零值(不是YES),但在我看来,更重要的是,它无法正确表达意图:
if(someVar==YES) { ... } // don't do this!
if(someVar==NO ) { ... } // don't do this either!
换句话说,按预期使用和记录使用构造,您可以避免遭受C语言痛苦的困扰。
我相信有是之间的差异bool
和BOOL
,看看这个网页为什么的解释:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html
因为BOOL
是unsigned char
基本类型,所以类型变量BOOL
可以包含YES
和以外的其他值NO
。
考虑以下代码:
BOOL b = 42;
if (b) {
printf("b is not NO!\n");
}
if (b != YES) {
printf("b is not YES!\n");
}
输出为:
b不是NO!
b不是YES!
对于大多数人来说,这是不必要的问题,但是如果您确实想要布尔值,最好使用bool
。我应该补充:iOS SDK通常BOOL
在其接口定义上使用,因此必须坚持使用BOOL
。
bool
,因此使用an int
或char
作为布尔值是一种传统,有时使用#define隐藏差异,有时则没有。实际上,我不确定即使当前的标准是否也需要bool
以防止检查其内部结构的方式实施。
printf
讲的是谎言。的值为b
not YES
,它是“非零”,这是条件测试的结果。所以您应该拥有printf("b is not zero")
,但不一定与相同YES
。在这种情况下,b
既是“非零”又是“不是”。
我对此进行了详尽的测试。我的结果应该说明一切:
//These will all print "1"
NSLog(@"%d", true == true);
NSLog(@"%d", TRUE == true);
NSLog(@"%d", YES == true);
NSLog(@"%d", true == TRUE);
NSLog(@"%d", TRUE == TRUE);
NSLog(@"%d", YES == TRUE);
NSLog(@"%d", true == YES);
NSLog(@"%d", TRUE == YES);
NSLog(@"%d", YES == YES);
NSLog(@"%d", false == false);
NSLog(@"%d", FALSE == false);
NSLog(@"%d", NO == false);
NSLog(@"%d", false == FALSE);
NSLog(@"%d", FALSE == FALSE);
NSLog(@"%d", NO == FALSE);
NSLog(@"%d", false == NO);
NSLog(@"%d", FALSE == NO);
NSLog(@"%d", NO == NO);
//These will all print "0"
NSLog(@"%d", false == true);
NSLog(@"%d", FALSE == true);
NSLog(@"%d", NO == true);
NSLog(@"%d", false == TRUE);
NSLog(@"%d", FALSE == TRUE);
NSLog(@"%d", NO == TRUE);
NSLog(@"%d", false == YES);
NSLog(@"%d", FALSE == YES);
NSLog(@"%d", NO == YES);
NSLog(@"%d", true == false);
NSLog(@"%d", TRUE == false);
NSLog(@"%d", YES == false);
NSLog(@"%d", true == FALSE);
NSLog(@"%d", TRUE == FALSE);
NSLog(@"%d", YES == FALSE);
NSLog(@"%d", true == NO);
NSLog(@"%d", TRUE == NO);
NSLog(@"%d", YES == NO);
输出为:
2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.072 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.076 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.082 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.091 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.092 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.097 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.098 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.101 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0
if
或a中的非布尔值的语言感到不舒服while
。像... while("guitar gently weeps")
不应该工作...
if (user_id = ROOT_UID)
true
和之间的主要区别(危险!)YES
是JSON序列化。
例如,我们有JSON类型的服务器请求,需要在JSON情况下发送true / false:
NSDictionary *r1 = @{@"bool" : @(true)};
NSDictionary *r2 = @{@"bool" : @(YES)};
NSDictionary *r3 = @{@"bool" : @((BOOL)true)};
然后我们将其转换为JSON字符串,然后发送为
NSData *data = [NSJSONSerialization dataWithJSONObject:requestParams options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
结果是
jsonString1 // {"bool":1}
jsonString2 // {"bool":true}
jsonString3 // {"bool":true}
由于API逻辑,jsonString1
可能导致错误。
因此,请注意Objective-C中的布尔值。
综上所述,仅精确@YES
和强制转换的值@((BOOL)expression)
是__NSCFBoolean
类型,并true
通过JSON序列化转换为。其他任何类似@(expression1 && expression2)
(even @(YES && YES)
)的表达式都是__NSCFNumber (int)
类型,并1
在JSON中转换为。
PS您可以简单地使用字符串值的布尔值
@{@"bool" : @"true"}; // in JSON {"bool":true}
这里没有人提到过一个微妙的错误,我想我应该包括...更多是逻辑错误,而不是其他任何错误:
int i = 2;
if(i); //true
if(i==YES); // false
if((!!i)==YES); //true
所以这里的问题就是,(YES==1)
在C语言中,比较不是布尔值,而是基于值的值。
因为YES
它只是一个#define
(而不是语言固有的东西),所以它必须具有一定的价值,并且1
最有意义。
我认为他们在很多情况下都添加“是/否”,这更加不言自明。例如:
[button setHidden:YES];
听起来比
[button setHidden:TRUE];
首先,让我们检查什么是对与错,以及首先赋予它们含义的含义。
我们可以在lambda演算中构造一个名为if a then b else c的结构,如下所示:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
在JavaScript中,如下所示:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
为了使ifThenElse有用,我们需要一个选择“ true”或“ left”的函数,并在忽略另一个选项的同时进行选择,或者选择一个“ false”的函数来选择“ true”。
我们可以如下定义这些功能:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
在JavaScript中,它看起来像这样:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
现在我们可以执行以下操作
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
使用doThis和doThat为(\ a。()),因为lambda演算不提供任何服务,例如打印/数学/字符串,我们所能做的就是什么都不做,说我们做了(后来作弊了,将其替换为服务中的我们提供副作用的系统)
因此,让我们看看实际情况。
(function(True) {
return (function(False) {
return (function(ifThenElse) {
return (function(doThis) {
return (function(doThat) {
return ifThenElse(True)(doThis)(doThat);
});
});
});
})
})(function(a) {
return function(b) {
return a;
}
})(function(a) {
return function(b) {
return b;
}
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
})(function(a) { console.log("you chose LEFT!"); })
(function(a) {console.log("you chose RIGHT");})();
如果允许我们使用数组/映射/参数/或多个语句来拆分为多个函数,那么可以简化这种深层环境,但是我想保持纯粹,因为我可以将自己限制为仅一个参数的函数只要。
请注意,名称True / False没有固有的意义,我们可以轻松地将其重命名为yes / no,left / right,right / left,零/一,apple / orange。它的意义在于,无论做出什么选择,它仅是由做出选择的那种人引起的。因此,如果打印了“ LEFT”,我们知道选择器只能是正确的,并且基于此知识,我们可以指导进一步的决策。
所以总结一下
function ChooseRight(left) {
return function _ChooseRight_inner(right) {
return right;
}
}
function ChooseLeft(left) {
return function _ChooseLeft_inner(right) {
return left;
}
}
var env = {
'0': ChooseLeft,
'1': ChooseRight,
'false': ChooseRight,
'true': ChooseLeft,
'no': ChooseRight
'yes': ChooseLeft,
'snd': ChooseRight,
'fst': ChooseLeft
};
var _0 = env['0'];
var _1 = env['1'];
var _true = env['true'];
var _false = env['false'];
var yes = env['yes'];
var no = env['no'];
// encodes church zero or one to boolean
function lambda_encodeBoolean(self) {
return self(false)(true);
}
// decodes a Boolean to church zero or one
function lambda_decodeBoolean(self) {
console.log(self, self ? env['true'] : env['false']);
return self ? env['true'] : env['false'];
}
lambda_decodeBoolean('one' === 'two')(function() {
console.log('one is two');
})(function() {
console.log('one is not two');
})();
lambda_decodeBoolean('one' === 'one')(function() {
console.log('one is one');
})(function() {
console.log('one is not one');
})();