Objective-CでYES / NO、TRUE / FALSEとtrue / falseの違いはありますか?
-
03-07-2019 - |
質問
本当に簡単な質問。これらの値に違いはありますか(およびBOOLとboolに違いはありますか)?同僚はObjective-Cで異なることを評価すると述べましたが、それぞれの.hファイルのtypedefを見ると、YES / TRUE / trueはすべて 1
およびNO /として定義されていましたFALSE / falseはすべて 0
として定義されました。本当に違いはありますか?
解決
実用的な違いはありません 提供 BOOL
変数をブール値として使用します。 Cは、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
には の違いがあると思います。理由については、このWebページをご覧ください。
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はYESではありません!
ほとんどの人にとってこれは不必要な懸念事項ですが、ブール値が本当に必要な場合は、 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タイプのサーバーリクエストがあり、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
タイプであり、 JSONシリアル化を使用した true
。
@(expression1&& expression2)
( @(YES&& YES)
)のような他の式は、 __ NSCFNumber(int)
を入力し、JSONで 1
に変換します。
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
最も理にかなっています。
多くの場合、よりわかりやすいようにYES / NOを追加すると思います。例:
[button setHidden:YES];
より良い音
[button setHidden:TRUE];
最初に真と偽とは何か、それらの意味を最初に調べてみましょう。
次のように、ラムダ計算で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が役立つためには、関数&quot; true&quot;が必要です。右または左のいずれかを選択し、他のオプションを無視しながらそれを行います。または、関数「false」を無視します。これはオプション「quot; 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。())必要な副作用を提供するシステム内のサービスを使用)
では、これを実際に見てみましょう。
(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");})();
これは、配列/マップ/引数/または複数のステートメントを使用して複数の関数に分割することが許可された場合に簡素化できる深い環境ですが、維持したいのは、引数は1つだけです。
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');
})();
いいえ、YES / NOはTRUE / FALSE(1/0)を参照する別の方法です