0

私の知る限り、オプション (この例では Int) を使用する推奨される方法は次のとおりです。

var one:Int?

if var maybe = one {
  println(maybe)
}

次のようなことを行うためのより短い方法を使用することは可能ですか?

var one:Int?
var two:Int?
var three:Int?

var result1 = one + two + three // error because not using !
var result2 = one! + two! + three! // error because they all are nil

アップデート

私がやろうとしていることをより明確にするために、次のオプションがあります

var one:Int?
var two:Int?
var three:Int?

1つ、2つ、または3つがゼロかどうかはわかりません。それらが nil の場合は、追加で無視したくありません。それらに値がある場合は、追加したくありません。

私が知っている推奨方法を使用する必要がある場合、次のようになります: (ネストされていない)

var result = 0

if var maybe = one {
  result += maybe
}
if var maybe = two {
  result += maybe
}
if var maybe = three {
  result += maybe
}

これを行うためのより短い方法はありますか?

4

2 に答える 2

3

それがまさにオプショナルのポイントです — それらは nil であっても非 nil であってもかまいませんが、nil のときにそれらをアンラップするとエラーになります。オプションには次の 2 種類があります。

T?またOptional<T>

var maybeOne: Int?
// ...

// Check if you're not sure
if let one = maybeOne {
    // maybeOne was not nil, now it's unwrapped
    println(5 + one)
}

// Explicitly unwrap if you know it's not nil
println(5 + one!)

T!またImplicitlyUnwrappedOptional<T>

var hopefullyOne: Int!
// ...

// Check if you're not sure
if hopefullyOne {
    // hopefullyOne was not nil
    println(5 + hopefullyOne)
}

// Just use it if you know it's not nil (implicitly unwrapped)
println(5 + hopefullyOne)

複数のオプションを一度にチェックする必要がある場合は、次のことを試してみてください。

if maybeOne && maybeTwo {
    println(maybeOne! + maybeTwo!)
}

if hopefullyOne && hopefullyTwo {
    println(hopefullyOne + hopefullyTwo)
}

let opts = [maybeOne, maybeTwo]
var total = 0
for opt in opts {
    if opt { total += opt! }
}

let(少なくとも今のところ、オプションのバインディング構文を一度に複数のオプションで使用することはできないようです...)

または、さらに楽しみたい場合は、より一般的で Swifty なものを使用します。

// Remove the nils from a sequence of Optionals
func sift<T, S: Sequence where S.GeneratorType.Element == Optional<T>>(xs: S) -> GeneratorOf<T> {
    var gen = xs.generate()
    return GeneratorOf<T> {
        var next: T??
        do {
            next = gen.next()
            if !next { return nil } // Stop at the end of the original sequence
        } while !(next!) // Skip to the next non-nil value
        return next!
    }
}

let opts: [Int?] = [1, 3, nil, 4, 7]
reduce(sift(opts), 0) { $0 + $1 } // 1+3+4+7 = 15
于 2014-07-09T07:22:26.610 に答える
3

簡単な注意 -if letオプションのバインディングに推奨されます - 可能な場合は常に let を使用する必要があります。

おそらく、オプションはこの状況には適していません。デフォルト値が 0 の標準 Int にしないのはなぜですか? その後、操作は簡単になり、値を処理しているときではなく、割り当ての時点で None 値の処理について心配することができますか?

ただし、本当にこれを行いたい場合は、オプションを配列に入れて使用するreduceことをお勧めします。

    let sum = [one,two,three,four,five].reduce(0) {
        if ($1) {
            return $0 + $1!
        }
        return $0
    }
于 2014-07-09T07:44:12.240 に答える