回答:
実用的な違いはありませんあなたが使用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
:理由の説明のために、この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はNOではありません!
bはYESではありません!
ほとんどの人にとってこれは不必要な懸念事項ですが、本当にブール値が必要な場合はを使用することをお勧めしますbool
。追加する必要があります:iOS SDKは通常BOOL
、インターフェイス定義で使用するため、これはに固執するための引数BOOL
です。
bool
たため、int
またはchar
をブール値として使用するのが伝統であり、場合によっては#defineを使用して違いを隠すこともしないこともあります。実際、現在の標準でさえbool
、内部構造の調査を妨げる方法で実装する必要があるかどうかはわかりません。
printf
は嘘をつきます。の値はb
でなくYES
、「ゼロでない」であり、これは条件がテストするものです。つまりprintf("b is not zero")
、と同じである必要はありませんYES
。この場合、b
は「ゼロではない」と「YESではない」の両方です。
私はこれについて徹底的なテストを行いました。私の結果はそれ自体が物語っています:
//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
またはでブール値以外の値をとる言語に慣れていません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
最も理にかなっています。
多くの場合、彼らは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を使用するには、右または左を選択し、他のオプションを無視してそれを行う関数「true」が必要です。または、オプション「true」を選択する関数「false」は使用しません。
これらの関数は次のように定義できます。
(\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。())であるので、ラムダ計算はprint / math / stringsなどのサービスを提供していないため、何もせずにそれを行ったと言うだけで済みます(後でそれを私たちが望む副作用を提供する私たちのシステム)
これを実際に見てみましょう。
(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に変更できます。それはどんな選択がなされても、それはそれを作った選択者の種類によってのみ引き起こされるという意味で重要です。したがって、「LEFT」が印刷されている場合、セレクターはtrueである可能性があることがわかります。この知識に基づいて、さらに決定を下すことができます。
要約すると
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');
})();