函数 throws AND returns optional.. 可以在一行中有条件地解包吗?
Function throws AND returns optional.. possible to conditionally unwrap in one line?
我正在使用一个 SQLite 库,其中查询 return 可选值并可能引发错误。我想有条件地解包该值,或者如果它 return 是一个错误则接收 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?
应用于可选表达式不会添加另一个可选级别,因此“简单”的可选绑定就足够了。如果函数没有抛出错误并且没有 return nil
,它就会成功。 val
然后绑定到展开的结果:
if let val = try? getSomething() {
// ...
}
(Swift ≤ 4 的先前答案:) 如果一个函数抛出 和 return 一个可选
func getSomething() throws -> Value? { ... }
然后try? getSomething()
return一个"double optional"的
输入 Value??
并且你必须解包两次:
if let optval = try? getSomething(), let val = optval {
}
这里第一个绑定 let optval = ...
如果函数成功了
不抛出,第二次绑定let val = optval
成功
如果 return 值不是 nil
.
这可以通过 case let
模式匹配到
来缩短
if case let val?? = try? getSomething() {
}
其中 val??
是 .some(.some(val))
的快捷方式。
我喜欢 Martin 的回答,但想展示另一个选项:
if let value = (try? getSomething()) ?? nil {
}
这具有在 if
、guard
或 switch
语句之外工作的优势。类型说明符 Any?
不是必需的,只是为了表明它 returns 是可选的:
let value: Any? = (try? getSomething()) ?? nil
我正在使用一个 SQLite 库,其中查询 return 可选值并可能引发错误。我想有条件地解包该值,或者如果它 return 是一个错误则接收 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?
应用于可选表达式不会添加另一个可选级别,因此“简单”的可选绑定就足够了。如果函数没有抛出错误并且没有 return nil
,它就会成功。 val
然后绑定到展开的结果:
if let val = try? getSomething() {
// ...
}
(Swift ≤ 4 的先前答案:) 如果一个函数抛出 和 return 一个可选
func getSomething() throws -> Value? { ... }
然后try? getSomething()
return一个"double optional"的
输入 Value??
并且你必须解包两次:
if let optval = try? getSomething(), let val = optval {
}
这里第一个绑定 let optval = ...
如果函数成功了
不抛出,第二次绑定let val = optval
成功
如果 return 值不是 nil
.
这可以通过 case let
模式匹配到
if case let val?? = try? getSomething() {
}
其中 val??
是 .some(.some(val))
的快捷方式。
我喜欢 Martin 的回答,但想展示另一个选项:
if let value = (try? getSomething()) ?? nil {
}
这具有在 if
、guard
或 switch
语句之外工作的优势。类型说明符 Any?
不是必需的,只是为了表明它 returns 是可选的:
let value: Any? = (try? getSomething()) ?? nil