論理AND演算子&&を使用してif letを実行する


93

if letステートメントを省略形として使用して、オプションのnilをチェックしてからラップを解除できることはわかっています。

ただし、論理AND演算子を使用して、それを別の式と組み合わせたいと思い&&ます。

したがって、たとえば、ここでは、オプションのチェーンを行ってラップを解除し、オプションでrootViewControllerをtabBarControllerにダウンキャストします。しかし、ifステートメントをネストするのではなく、それらを組み合わせたいと思います。

if let tabBarController = window!.rootViewController as? UITabBarController {
    if tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
 }

組み合わせた寄付:

if let tabBarController = window!.rootViewController as? UITabBarController &&
    tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
}

上記はコンパイルエラー示します未解決の識別子 'tabBarController'の使用

簡素化:

if let tabBarController = window!.rootViewController as? UITabBarController && true {
   println("do stuff")
}

これにより、コンパイルエラーが発生します。条件付きバインディングのバインド値は、オプションタイプである必要があります。さまざまな構文のバリエーションを試みた結果、それぞれに異なるコンパイラエラーが発生しました。順序と括弧の組み合わせはまだわかりません。

それで、問題は、それが可能であり、もしそうなら正しい構文は何ですか?

私はこれをしたいという注意if文のないswitch文または三項?演算子。


質問にエラーメッセージを提供することは常に良い考えです。
zaph 2014

これを実験したい人のためのより単純なステートメント:var foo : Int? = 10; if let bar = foo { if bar == 10 { println("Great success!") }}
DarkDust

使用時のエラーメッセージif let bar = foo && bar == 10Use of unresolved identifier "bar"(2番目barのもちろん)です。
DarkDust 2014

次のようにObjective CのfirstObjectを使用して上記の例を短くすることができたことに注意してください。UINavigationController {
Max MacLeod

1
1. bridgeToObjectiveCベータ5でなくなった(そして、おそらく一般的な使用を意図したものではなかった)。2. とにかくfirst、Swiftの組み込みArray型にメソッドがあります。
リクスター2014

回答:


143

Swift 1.2以降、これが可能になりましたスウィフト1.2とXcode 6.3のベータリリースノートの状態:

if letを使用したより強力なオプションのアンラップ — if let構成では、複数のオプションを一度にアンラップできるだけでなく、中間のブール条件を含めることができます。これにより、不要なネストなしで条件付き制御フローを表現できます。

上記のステートメントを使用すると、構文は次のようになります。

if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 {
        println("do stuff")
}

これはwhere節を使用します。

別の例では、今度はにキャストAnyObjectしてInt、オプションをアンラップし、アンラップされたオプションが条件を満たしていることを確認します。

if let w = width as? Int where w < 500
{
    println("success!")
}

現在Swift 3を使用している人のために、「where」はコンマに置き換えられました。したがって、同等のものは次のようになります。

if let w = width as? Int, w < 500
{
    println("success!")
}

2
これが選ばれた答えになるはずです。
Francis.Beauchamp

はい、変更されました。その時のブライアンの答えは正しかった
Max MacLeod

58

スウィフト3マックス・マクラウドの例は次のようになります。

if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
    println("do stuff")
}

whereに置き換えられました,


10
|は&&のためのものです|&のために何がありますか|| ?
jeet.chanchawat

9
@ jeet.chanchawatの論理ORは、このコンテキストでは意味がありません。if letオプションが正常にアンラップされ、新しい変数名に割り当てられている場合にのみ続行できます。あなたが言ったならOR <something else>、あなたは簡単にの全体の目的を回避することができますif let。論理ORの場合は、通常のif処理を行い、本文の内部で最初のオブジェクトがその時点ではまだオプション(ラップされていない)であることを扱います。
jhabbott 2017年

37

マックスの答えは正しく、これを行う1つの方法です。ただし、このように書くと、次のことに注意してください。

if let a = someOptional where someBool { }

someOptional式が最初に解決されます。失敗した場合、someBool式は評価されません(期待どおりの短絡評価)。

これを別の方法で記述したい場合は、次のようにできます。

if someBool, let a = someOptional { }

この場合someBool、最初に評価され、trueと評価された場合にのみsomeOptional式が評価されます。


5

Swift 4、私は使用します、

let i = navigationController?.viewControllers.index(of: self)
if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] {
    // access parent
}

4

それは不可能。

Swift文法から

IFステートメントの文法

ifステートメント→ if if条件コードブロックelse-clause­o

if条件→式| 宣言

else-clause→ else code-block | そうでなければif文

ifステートメントの条件の値には、BooleanTypeプロトコルに準拠するタイプが必要です。オプションのバインディングで説明されているように、条件はオプションのバインディング宣言にすることもできます。

if-conditionは式または宣言でなければなりません。式と宣言の両方を持つことはできません。

let foo = bar宣言であり、に準拠する値に評価されませんBooleanType。定数/変数を宣言しますfoo

あなたの元の解決策は十分に良いです、それは条件を組み合わせるよりはるかに読みやすいです。


しかし確かに「if let」-これは有効なSwift構文です-は式と宣言の両方ですか?
Max MacLeod 2014

@MaxMacLeod let foo = barは式ではなく宣言です。できないlet boolValue = (let foo = bar)
ブライアンチェン

わかりましたが、11ページのSwiftガイドを引用すると、例は次のようになります。optionalNameは式である必要があります。optionalNameがオプションでない場合は、trueと評価されます。次に、ステートメントの2番目の部分が開始され、ラップされていないオプションが名前に割り当てられます。したがって、問題は、「optionalNameはオプションではない」が式である場合、論理ANDで展開できるということです。ところで私はあなたがおそらくそれができないという点で正しいと思います。
Max MacLeod 2014

-1

あなたの元の命題はそれほど悪くはないと思います。(厄介な)代替案は次のようになります。

if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 {
    println("do stuff")
}

1
ただし、tabBarController再度キャストするにはコードを記述する必要があります
Bryan Chen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.