据我所知,推荐使用optionals的方法(本例中为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?
我不知道一两个或三个是否为零。如果它们是零,我不想在添加中忽略它们。如果他们有价值,我不想添加它们。
如果我必须使用我所知道的推荐方式,它看起来像这样:(未经证实的)
var result = 0
if var maybe = one {
result += maybe
}
if var maybe = two {
result += maybe
}
if var maybe = three {
result += maybe
}
有更短的方法吗?
答案 0 :(得分:3)
这正是选项的重点 - 它们可能是零或非零,但是当它们为零时将它们展开是错误。选项有两种类型:
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
答案 1 :(得分:3)
快速注释 - if let
是可选绑定的首选 - 应尽可能使用。
也许Optionals对于这种情况不是一个好的选择。为什么不将它们设为标准Ints,默认值为0?那么任何操作都变得微不足道,你可以担心在赋值时处理None值,而不是在你处理值时?
但是,如果确实想要这样做,那么更整洁的选择是将Optionals放入数组并在其上使用reduce
:
let sum = [one,two,three,four,five].reduce(0) {
if ($1) {
return $0 + $1!
}
return $0
}