6

I'm learning Swift and I'm testing the following code

var value: String; do { value = try getValue() } catch { value = "Default Value" } 

which can be shortened to

let value = (try? getValue()) ?? "Default Value" 

It works but I feel I may be missing a more obvious solution.

7
  • 2
    I don't think there is another simpler solution . You could use if let value = try? getValue() { but that's just another variant of your first version. Commented Mar 11, 2017 at 18:13
  • 1
    What's the question? Commented Mar 11, 2017 at 18:37
  • @matt Is there a better way? I'm trying to do things the Swift way rather than conflate my Javascript (Node) knowledge onto the Swift language. Commented Mar 11, 2017 at 18:42
  • 1
    The second solution is shorter, but throwing functions provide error information. Only the first method can give it to you. Commented Mar 11, 2017 at 18:50
  • 1
    @Wainage That's why in my answer, below, I explained how the try? works, just to make sure you're grasping what you're doing (and so that you see that it is right). Commented Mar 11, 2017 at 18:51

1 Answer 1

4

Your solution is just great, and extremely elegant.

I presume we would like to avoid saying var in the first line and initializing the variable later. In general, the way to initialize a value immediately with a complex initializer is to use a define-and-call construct:

let value: String = { do { return try getValue() } catch { return "Default Value" } }() 

And you would probably want to do that if the catch block was returning error information that you wanted to capture.

However, in this case, where you are disregarding the nature of the error, your expression is much more compact, and does precisely what you want done. try? will return an Optional, which will either be unwrapped if we succeed, or, if we fail, will return nil and cause the alternate value ("Default Value") to be used.

Sign up to request clarification or add additional context in comments.

3 Comments

Correct me if I'm wrong, but that is essentially a immediately invoked lambda? That is pretty slick especially if you need to deal with different errors.
"that is essentially a immediately invoked lambda" You bet your LISP. More discussion from me, here: apeth.com/swiftBook/ch02.html#SECdefineandcall And here: apeth.com/swiftBook/ch03.html#_computed_initializer
Thanks for that link and making this info available to the community. I will definitely be perusing it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.