一尘不染

函数抛出AND返回可选的..可能有条件地在一行中展开吗?

swift

我正在使用一个SQLite库,其中查询返回可选值,并且可能引发错误。我想有条件地解开该值,如果返回错误,则返回nil。我不太确定该如何措辞,此代码将对此进行解释,其外观如下:

func getSomething() throws -> Value? {
    //example function from library, returns optional or throws errors
}


func myFunctionToGetSpecificDate() -> Date? {
    if let specificValue = db!.getSomething() {
         let returnedValue = specificValue!
         // it says I need to force unwrap specificValue, 
         // shouldn't it be unwrapped already?

         let specificDate = Date.init(timeIntervalSinceReferenceDate: TimeInterval(returnedValue))
         return time
    } else {
         return nil
    }

}

有没有办法避免不得不在那儿强行打开包装?在更新到Swift3之前,我并没有被迫在此处强制展开。

以下是实际代码。只是尝试从所有条目中获取最新的时间戳:

func getLastDateWithData() -> Date? {
    if let max = try? db!.scalar(eventTable.select(timestamp.max)){

        let time = Date.init(timeIntervalSinceReferenceDate: TimeInterval(max!))

        // will max ever be nil here? I don't want to force unwrap!
        return time

    } else {
        return nil
    }
}

阅读 250

收藏
2020-07-07

共1个答案

一尘不染

更新:Swift 5开始,
try?应用于可选表达式不会添加其他级别的可选性,因此“简单”的可选绑定就足够了。如果函数没有引发错误并且没有返回,则表示成功nilval然后绑定到展开的结果:

if let val = try? getSomething() {
    // ...
}

(Swift≤4的先前答案:) 如果函数抛出 返回可选

func getSomething() throws -> Value? { ... }

然后try? getSomething()返回该类型的“双精度可选”,则Value??必须解开两次:

if let optval = try? getSomething(), let val = optval {

}

在这里,let optval = ...如果函数未抛出,则第一个绑定let val = optval成功;如果返回值不是,则第二个绑定成功nil

可以通过case let模式匹配缩短到

if case let val?? = try? getSomething() {

}

val??的快捷方式在哪里.some(.some(val))

2020-07-07