使用Swift编程语言中的可选项



据我所知,使用可选选项(本例中为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还是不是。如果它们是nil,我不希望它们在加法中被忽略。如果它们有值,我不希望它们被添加。

如果我必须使用我所知道的推荐方式,它看起来像这样:(unnested)

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

有更短的方法吗?

快速提示- if let是可选绑定的首选-应该尽可能使用let。

对于这种情况,选项可能不是一个好的选择。为什么不让它们成为标准的int类型,默认值为0呢?然后,任何操作都变得微不足道,您可以担心在赋值点处理None值,而不是在处理值时?

然而,如果你真的想要这样做,那么一个更简洁的选择是将可选项放入数组中,并在其上使用reduce:

    let sum = [one,two,three,four,five].reduce(0) {
        if ($1) {
            return $0 + $1!
        }
        return $0
    }

这正是可选的意义所在——它们可以是nil也可以是非nil,但是当它们为nil时展开它们是一个错误。有两种类型的可选:

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可选绑定语法与多个可选的一次,至少现在…)

或者更有趣的是,一些更通用和更快捷的东西:

// 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

最新更新