7

複数の値を持つ単純な if-let ステートメントを作成しようとしています。ブロックは、ifすべてのオプション変数が非 nil である場合にのみ実行されるべきでありif、通常の単一割り当ての if-let と同様に、ブロック内にのみ存在する新しい let-vars (定数?) に割り当てられる必要があります。

var a: String? = "A"
var b: String? // nil

if let (m, n) = (a, b) {
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
// error: Bound value in a conditional binding must be of Optional type
// this of course is because the tuple itself is not an Optional
// let's try that to be sure that's the problem...

let mysteryTuple: (String?, String?)? = (a, b)
if let (m, n) = mysteryTuple {
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
// yeah, no errors, but not the behavior I want (printed "m: A, n: nil")

// and in a different way:
if let m = a, n = b {
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
// a couple syntax errors (even though 'let m = a, n = b'
// works on its own, outside the if statement)

これは可能ですか?そうでない場合 (私は推測しています)、Apple は将来これを実装する予定 (または実装すべき) だと思いますか?

4

2 に答える 2

10

これはおそらく今では明らかですが、この期待される機能の探求は、Swift 1.2 のリリースで終了する可能性があります。

Swift ブログから: https://developer.apple.com/swift/blog/?id=22

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

要するに、where 句で値を制約することに加えて、求めていることを実行できるようになったということです。

if let a = foo(), b = bar() {
}
于 2015-05-28T20:45:44.937 に答える
8

可能かどうかを判断する前に、if - let ...条件が単一のオプション値で機能する理由を検討してください: このコードがコンパイルされる理由

if let constVar = testVar {
    ...
}

すべてのオプションの型LogicalValueが、オプションの値の null チェックを処理するプロトコルに準拠しているということです。

これは、オプションのタプルを使用したトリックも機能しなかった理由を説明していますLogicalValue。タプル自体がnullでないかどうかをチェックし、そのコンポーネントを無視する実装。Apple の決定の背後にある論理は明確です。すべての要素型がオプションである場合にタプルを例外にするのではなく、統一的なアプローチを取り、他のオプション型を扱うのと同じ方法でタプルを扱いました。

もちろん、実装しようとしているロジックの実装は、次のコード行を追加するだけで簡単に実装できます。

if a != nil && b != nil {
    let (m, n) = (a!, b!)
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
于 2014-07-18T17:57:01.433 に答える