Objective-c 中 YES/NO,TRUE/FALSE 和 true/false 之间有区别吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/615702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a difference between YES/NO,TRUE/FALSE and true/false in objective-c?
提问by Kevlar
Simple question really; is there a difference between these values (and is there a difference between BOOL and bool)? A co-worker mentioned that they evaluate to different things in Objective-C, but when I looked at the typedefs in their respective .h files, YES/TRUE/true were all defined as 1and NO/FALSE/false were all defined as 0. Is there really any difference?
真的很简单的问题;这些值之间有区别吗(BOOL 和 bool 之间是否有区别)?一位同事提到他们在 Objective-C 中对不同的东西进行了评估,但是当我查看他们各自的 .h 文件中的 typedef 时,YES/TRUE/true 都被定义为1,NO/FALSE/false 都被定义为0. 真的有什么区别吗?
采纳答案by Lawrence Dol
There is no practical difference providedyou use BOOLvariables as booleans. C processes boolean expressions based on whether they evaluate to 0 or not 0. So:
如果您将BOOL变量用作布尔值,则没有实际区别。C 根据布尔表达式的计算结果是否为 0 来处理它们。所以:
if(someVar ) { ... }
if(!someVar) { ... }
means the same as
意思是一样的
if(someVar!=0) { ... }
if(someVar==0) { ... }
which is why you can evaluate any primitive type or expression as a boolean test (including, e.g. pointers). Note that you should do the former, not the latter.
这就是为什么您可以将任何原始类型或表达式评估为布尔测试(包括例如指针)的原因。请注意,您应该做前者,而不是后者。
Note that there isa difference if you assign obtuse values to a so-called BOOLvariable and test for specific values, so always use them as booleans and only assign them from their #definevalues.
请注意,如果将钝值分配给所谓的变量并测试特定值,则存在差异BOOL,因此始终将它们用作布尔值并且仅从它们的#define值中分配它们。
Importantly, never test booleans using a character comparison -- it's not only risky because someVarcould be assigned a non-zero value which is not YES, but, in my opinion more importantly, it fails to express the intent correctly:
重要的是,永远不要使用字符比较来测试布尔值——这不仅有风险,因为someVar可以分配一个非 YES 的非零值,但在我看来,更重要的是,它无法正确表达意图:
if(someVar==YES) { ... } // don't do this!
if(someVar==NO ) { ... } // don't do this either!
In other words, use constructs as they are intended and documented to be used and you'll spare yourself from a world of hurt in C.
换句话说,按照预期和记录在案的方式使用构造,您将免于 C 语言的伤害世界。
回答by Dan J
I believe there isa difference between booland BOOL, check out this webpage for an explanation of why:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html
我相信有是之间的差异bool和BOOL,看看这个网页为什么的解释:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html
Because BOOLis an unsigned charrather than a primitive type, variables of type BOOLcan contain values other than YESand NO.
因为BOOL是一个unsigned char而不是原始类型,类型的变量BOOL可以包含除YESand之外的值NO。
Consider this code:
考虑这个代码:
BOOL b = 42;
if (b) {
printf("b is not NO!\n");
}
if (b != YES) {
printf("b is not YES!\n");
}
The output is:
输出是:
b is not NO!
b is not YES!
b不是NO!
b 不是 YES!
For most people this is an unnecessary concern, but if you really want a boolean it is better to use a bool. I should add: the iOS SDK generally uses BOOLon its interface definitions, so that is an argument to stick with BOOL.
对于大多数人来说,这是一个不必要的问题,但如果你真的想要一个布尔值,最好使用bool. 我应该补充一点:iOS SDK 通常BOOL在其接口定义上使用,因此这是坚持使用BOOL.
回答by Supuhstar
I did an exhaustive test on this. My results should speak for themselves:
我对此进行了详尽的测试。我的结果不言自明:
//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);
The output is:
输出是:
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
回答by Barry Wark
You might want to read the answers to this question. In summary, in Objective-C (from the definition in objc.h):
您可能想阅读这个问题的答案。总之,在Objective-C中(来自objc.h中的定义):
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#define OBJC_BOOL_DEFINED
#define YES (BOOL)1
#define NO (BOOL)0
回答by malex
The main (dangerous!) difference between trueand YESis in JSON serialization.
true和之间的主要(危险!)区别在于YESJSON 序列化。
For example, we have JSON-type server request and need to send true/false in json sence:
例如,我们有一个 JSON 类型的服务器请求,需要在 json sence 中发送 true/false:
NSDictionary *r1 = @{@"bool" : @(true)};
NSDictionary *r2 = @{@"bool" : @(YES)};
NSDictionary *r3 = @{@"bool" : @((BOOL)true)};
Then we convert it to JSON string before sending as
然后我们在发送之前将其转换为 JSON 字符串
NSData *data = [NSJSONSerialization dataWithJSONObject:requestParams options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
The result is
结果是
jsonString1 // {"bool":1}
jsonString2 // {"bool":true}
jsonString3 // {"bool":true}
Due to API logic jsonString1could result in an error.
由于 API 逻辑jsonString1可能会导致错误。
So be careful with booleans in Objective-C.
所以要小心使用 Objective-C 中的布尔值。
To sum up, only exact @YESand casted value as @((BOOL)expression)are of __NSCFBooleantype and converted to truewith JSON serialization.
Any other expressions like @(expression1 && expression2)(even @(YES && YES)) are of __NSCFNumber (int)type and converted to 1in JSON.
综上所述,仅精确@YES和铸造值@((BOOL)expression)是的__NSCFBoolean类型,并转换为true与JSON序列。像@(expression1 && expression2)(even @(YES && YES))这样的任何其他表达式都属于__NSCFNumber (int)类型并转换为1JSON。
P.S. You can simply use string-valued boolean
PS您可以简单地使用字符串值布尔值
@{@"bool" : @"true"}; // in JSON {"bool":true}
回答by Grady Player
There is a subtle bug that no one has mentioned here, that I thought I would include... more of a logical error than anything:
有一个微妙的错误,这里没有人提到,我想我会包括......更多的是逻辑错误:
int i = 2;
if(i); //true
if(i==YES); // false
if((!!i)==YES); //true
so the issue here is just that (YES==1)and in C the comparison isn't a boolean one, but one based on value.
所以这里的问题就是这样(YES==1),在 C 中,比较不是布尔值,而是基于值的比较。
because YESis just a #define(rather than something intrinsic to the language), it has to be some value, and 1makes the most sense.
因为YES只是一个#define(而不是语言固有的东西),它必须具有某种价值,并且1最有意义。
回答by Marco
I think they add YES/NO to be more self-explanatory in many cases. For example:
我认为他们在许多情况下添加 YES/NO 是为了更不言自明。例如:
[button setHidden:YES];
sounds better than
听起来比
[button setHidden:TRUE];
回答by Dmitry
First let's examine what true and false is and what gives them meaning in the first place.
首先让我们检查一下什么是真什么是假,以及是什么赋予了它们意义。
we can construct a structure called if a then b else c in lambda calculus as follows:
我们可以在 lambda 演算中构造一个名为 if a then b else c 的结构,如下所示:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
In JavaScript, This looks like this:
在 JavaScript 中,这看起来像这样:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
in order for ifThenElse to be useful, we need a function "true" that chooses either right or left, and does that while ignoring the other option, or a function "false" that chooses the option "true" doesn't take.
为了使 ifThenElse 有用,我们需要一个函数“true”来选择右或左,并在忽略另一个选项的情况下这样做,或者选择选项“true”的函数“false”不接受。
We can define these functions as follows:
我们可以定义这些函数如下:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
in JavaScript it looks like this:
在 JavaScript 中,它看起来像这样:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
now we can do the following
现在我们可以执行以下操作
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
with doThis and doThat being (\a. ()) because lambda calculus does not offer any services such as printing/math/strings, all we can do is do nothing and say we did it(and later cheat by replacing it with services in our system that provide side effects we want)
doThis 和 doThat 是 (\a. ()) 因为 lambda 演算不提供任何服务,例如打印/数学/字符串,我们所能做的就是什么都不做并说我们做到了(然后通过用服务替换它来作弊我们的系统提供了我们想要的副作用)
so let's see this in action.
所以让我们看看它的实际效果。
(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");})();
That's a deep environment that could be simplified if we were allowed to use arrays/maps/arguments/or more than one statement to split into multiple functions, but i want to keep is as pure as I can limiting myself to functions of exactly one argument only.
这是一个可以简化的深层环境,如果我们被允许使用数组/映射/参数/或多个语句来拆分为多个函数,但我想保持尽可能纯粹,因为我可以将自己限制在只有一个参数的函数只要。
notice that the name True/False has no inherent significance, we can easily rename them to yes/no, left/right, right/left, zero/one, apple/orange. It has significance in that whatever choice is made, it is only caused by the kind of chooser made it. So if "LEFT" is printed, we know that the chooser could only be true, and based on this knowledge we can guide our further decisions.
请注意,名称 True/False 没有固有的意义,我们可以轻松地将它们重命名为 yes/no、left/right、right/left、0/one、apple/orange。它的意义在于,无论做出什么选择,它都只是由做出它的那种选择者造成的。因此,如果打印“LEFT”,我们就知道选择器只能为真,并且基于这些知识我们可以指导我们进一步的决策。
So to summarize
所以总结一下
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');
})();
回答by Marco
No, YES/NO is a different way to refer to TRUE/FALSE(1/0)
不,是/否是指代 TRUE/FALSE(1/0) 的不同方式

