web-dev-qa-db-ja.com

ifステートメントで複数のオプションをアンラップします

2つのオプションを1つのifステートメントでラップ解除したいのですが、コンパイラはパスワード定数の演算子の後の予想される式について苦情を言います。その理由は何でしょうか?

    if let email = self.emailField?.text && let password = self.passwordField?.text
    {
        //do smthg
    }

Swiftで行われました。

60
LeonS

素晴らしいニュース。 Swift 1.2(XCode 6.3 beta、2/9/15リリース)で、複数行のオプションを1行でアンラップすることがサポートされるようになりました。

タプル/スイッチのパターンマッチングはもう必要ありません。実際には、元の推奨構文に非常に近い(聞いてくれてありがとう、Apple!)

if let email = emailField?.text, password = passwordField?.text {

}

もう1つの良い点は、「保護条件」にwhereを追加できることです。

var email: String? = "[email protected]"
var name: String? = "foo"

if let n = name, e = email where contains(e, "@") {
  println("name and email exist, email has @")
}

参照: XCode 6.3ベータリリースノート

131
smithclay

Swift 3:の更新

if let email = emailField?.text, let password = passwordField?.text {
}

各変数の前にletキーワードを付ける必要があります

42
Henningsson

タプルでオプションをラップし、switchを使用してパターンマッチを行う方法はありますか?

switch (self.emailField?.text, self.passwordField?.text) {
case let (.Some(email), .Some(password)):
    // unwrapped 'email' and 'password' strings available here
default:
    break
}

確かに少しうるさいですが、少なくともwhere句と組み合わせることもできます。

25
Joel Edström

使い方

if let x = y {
}

同等ではありません

if (let x = y) { // this is actually not allowed
}

「if let」は実質的に2ワードのキーワードで、これは次と同等です

if y != nil {
    let x = y!
    // rest of if let block
}
9
Grimxn

Before Swift 1.2

@Jamesと同様に、unwrap関数も作成しましたが、これは既存のif let制御フローの場合、クロージャを使用する代わりに:

func unwrap<T1, T2>(optional1: T1?, optional2: T2?) -> (T1, T2)? {
  switch (optional1, optional2) {
  case let (.Some(value1), .Some(value2)):
    return (value1, value2)
  default:
    return nil
  }
}

これは次のように使用できます。

if let (email, password) = unwrap(self.emailField?.text, self.passwordField?.text)
{
  // do something
}

から: https://Gist.github.com/tomlokhorst/f9a826bf24d16cb5f6a

もっと多くのケースを処理したい場合(2つのフィールドのいずれかnilの場合など)、switchステートメントを使用する方がよいことに注意してください。

5
Tom Lokhorst

スイフト4

if let suggestions = suggestions, let suggestions1 = suggestions1 {

        XCTAssert((suggestions.count > suggestions1.count), "TEST CASE FAILED: suggestion is nil. delete sucessful");
}
2
Wasim

上記のコードが機能しない理由を説明することはできませんが、これは良い代替品です。

if let email = self.emailField?.text 
{
    if let password = self.passwordField?.text 
    {
        //do smthg
    }
}
1
Ashley Mills

@Joelの答えに基づいて、ヘルパーメソッドを作成しました。

func unwrap<T, U>(a:T?, b:U?, handler:((T, U) -> ())?) -> Bool {
    switch (a, b) {
    case let (.Some(a), .Some(b)):
        if handler != nil {
            handler!(a, b)
        }
        return true
    default:
        return false
    }
}

// 使用法

unwrap(a, b) {
    println("\($0), \($1)")
}
0
James Tang