我正在使用一个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 } }
更新: 从 Swift 5开始, try?应用于可选表达式不会添加其他级别的可选性,因此“简单”的可选绑定就足够了。如果函数没有引发错误并且没有返回,则表示成功nil。val然后绑定到展开的结果:
try?
nil
val
if let val = try? getSomething() { // ... }
(Swift≤4的先前答案:) 如果函数抛出 并 返回可选
func getSomething() throws -> Value? { ... }
然后try? getSomething()返回该类型的“双精度可选”,则Value??必须解开两次:
try? getSomething()
Value??
if let optval = try? getSomething(), let val = optval { }
在这里,let optval = ...如果函数未抛出,则第一个绑定let val = optval成功;如果返回值不是,则第二个绑定成功nil。
let optval = ...
let val = optval
可以通过case let模式匹配缩短到
case let
if case let val?? = try? getSomething() { }
val??的快捷方式在哪里.some(.some(val))?
val??
.some(.some(val))