据我所知,使用可选选项(本例中为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