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?

我不知道一、二或三是否为零。如果它们为零,我不希望它们在添加中被忽略。如果它们具有价值,我不希望它们被添加。

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

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 时解包是错误的。有两种类型的选项:

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。

对于这种情况,Optionals 可能不是一个好的选择。为什么不将它们设为默认值为 0 的标准 Int?然后任何操作都变得微不足道,您可以担心在分配时处理 None 值,而不是在处理值时?

但是,如果您真的想这样做,那么一个更简洁的选择是将 Optionals 放入一个数组并reduce在其上使用:

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