Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
723 views
in Technique[技术] by (71.8m points)

swift - Function throws AND returns optional.. possible to conditionally unwrap in one line?

I am using an SQLite library in which queries return optional values as well as can throw errors. I would like to conditionally unwrap the value, or receive nil if it returns an error. I'm not totally sure how to word this, this code will explain, this is what it looks like:

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
    }

}

Is there a way to avoid having to force unwrap there? Prior to updating to Swift3, I wasn't forced to force unwrap here.

The following is the actual code. Just trying to get the latest timestamp from all entries:

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
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Update: As of Swift 5, try? applied to an optional expression does not add another level of optionality, so that a “simple” optional binding is sufficient. It succeeds if the function did not throw an error and did not return nil. val is then bound to the unwrapped result:

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

(Previous answer for Swift ≤ 4:) If a function throws and returns an optional

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

then try? getSomething() returns a "double optional" of the type Value?? and you have to unwrap twice:

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

}

Here the first binding let optval = ... succeeds if the function did not throw, and the second binding let val = optval succeeds if the return value is not nil.

This can be shortened with case let pattern matching to

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

}

where val?? is a shortcut for .some(.some(val)).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...