Есть ли разница между YES/NO,TRUE/FALSE и true / false в objective-c?
простой вопрос на самом деле; есть ли разница между этими значениями (и есть ли разница между BOOL и bool)? Коллега отметил, что они оценивают разные вещи в Objective-C, но когда я посмотрел на типов в их .H файлы, да / TRUE / true все были определены как 1 и NO / FALSE / false были определены как 0. Разве есть разница?
9 ответов:
нет никакой практической разницы предоставил вы используете
BOOLпеременные логическими значениями. C обрабатывает булевы выражения, основанные на том, оцениваются ли они в 0 или нет 0. Итак:if(someVar ) { ... } if(!someVar) { ... }означает то же, что
if(someVar!=0) { ... } if(someVar==0) { ... }именно поэтому вы можете оценить любой примитивный тип или выражение как логический тест (включая, например, указатели). Обратите внимание, что вы должны делать первое, а не второе.
обратите внимание, что там и разница, если вы назначаете тупые значения так называемому
BOOLпеременная и тест для определенных значений, поэтому всегда используйте их как логические значения и назначайте их только из их#defineзначения.важно, никогда не тестируйте булевы, используя сравнение символов - это не только рискованно, потому что
someVarможет быть присвоено ненулевое значение, которое не является да, но, на мой взгляд, что более важно, он не может выразить намерение правильно: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 не нет!
b - это не да!для большинства людей это ненужная забота, но если вы действительно хотите логическое значение, лучше использовать
bool. Я должен добавить: iOS SDK обычно используетBOOLна его интерфейсных определениях, так что это аргумент, чтобы придерживатьсяBOOL.
Я сделал исчерпывающий тест на этом. Мои результаты должны говорить сами за себя:
//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
вы можете прочитать ответы на этот вопрос. Таким образом, в 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
основной (опасно!) разница между
trueиYESнаходится в сериализации JSON.например, у нас есть запрос сервера типа JSON и нужно отправить true / false в JSON sence:
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.
P. S. Вы можете использовать
@{@"bool" : @"true"}; // {"bool":true}
Я думаю, что они добавляют Да / нет, чтобы быть более понятным во многих случаях. Например:
[button setHidden:YES];звучит лучше, чем
[button setHidden:TRUE];
есть тонкая ошибка, которую никто не упомянул здесь, что я думал, что включу... скорее логическая ошибка, чем что-либо:
int i = 2; if(i); //true if(i==YES); // false if((!!i)==YES); //trueтак что проблема здесь только в том, что
(YES==1)и в C сравнение не является логическим, а основано на значении., потому что
YESэто просто#define(а не что-то присущее язык), это должно быть какое-то значение, а1имеет наибольший смысл.
сначала давайте рассмотрим, что такое истина и ложь и что дает им смысл в первую очередь.
мы можем построить структуру, называемую 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", которая выбирает либо вправо, либо влево, и делает это, игнорируя другой параметр, или функция "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 being (\a. ()) поскольку лямбда-исчисление не предлагает никаких услуг, таких как печать/математика/строки, все, что мы можем сделать, это ничего не делать и сказать, что мы это сделали (а затем обмануть, заменив его услугами в нашей системе, которые обеспечивают побочные эффекты, которые мы хотим)
так давайте посмотрим на это в действии.
(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, zero/one, apple/orange. Это имеет значение в что какой бы выбор ни был сделан, он вызван только тем, какой выбор сделал его. Поэтому, если" левый " напечатан, мы знаем, что выбор может быть только истинным, и на основе этого знания мы можем направлять наши дальнейшие решения.
Итак
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'); })();
Comments