使用Swift编程语言中的选项

时间:2014-07-09 07:14:51

标签: swift optional-variables

据我所知,推荐使用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
}

有更短的方法吗?

2 个答案:

答案 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
    }