4

Swift 2.0 added do {} catch {} which can be used like so:

do { let jsonData = try NSJSONSerialization.dataWithJSONObject(params, options: []); } catch let jsonError as NSError { print(jsonError); } 

but I've also seen in in my 2.0 converted classes the catch implemented with an underscore:

do { let jsonData = try NSJSONSerialization.dataWithJSONObject(params, options: []); } catch _ { } 

what makes it especially confusing is why not just provide nothing after catch which is perfectly valid code:

do { let jsonData = try NSJSONSerialization.dataWithJSONObject(params, options: []); } catch { } 

What is that underscore _, what can I do with it, how would I implement that in my own function signatures? In the previous Swift 1.2 declaration I didn't use the NSError so it makes sense that the conversion is throwing the error away but why use _?

9
  • 1
    @Aaron Brager if you read both questions carefully you'll see that they are not actually related, my question isn't about method signatures. Commented Jul 10, 2015 at 0:05
  • Presumably it just means that you are not assigning any name to an error you catch and hence not declaring it. Maybe this is preferable if you don't actually want to do anything with the error in the catch block. Commented Jul 10, 2015 at 0:07
  • @myles thats what I thought as well but if that were the case you can just not provide anything after the catch statement, ie it just says catch { so why would it convert to having a _? Commented Jul 10, 2015 at 0:08
  • Did Xcode automatically convert it from a declaration to an underscore or was it explicitly written this way? If automatically converted I've read that it can do this if the previously declared variable wasn't actually used in the following block. So in your example above, if jsonError wasn't actually used in the catch block Xcode may automatically conver this to _. If it's because of this maybe they just didn't implement the process cleverly enough to do it without an _ if one isn't required. Commented Jul 10, 2015 at 0:14
  • 1
    I think because it does this convert with other things too, like with if let ... if the variable name was not actually used in the following block. If they were to not put the _ in these places the code wouldn't actually work. Hence it does _ everywhere to be safe, even though in some places you may not actually need it. Commented Jul 10, 2015 at 0:21

2 Answers 2

3

You're asking a question about an automatic conversion. It's just a starting place! Apple doesn't know what you want to do, so they provide a completely minimal neutral catch-all catch block — it does nothing at all, but we compile because there's a catch-all. Obviously if you want to capture the error variable, you will delete the _ and capture the error variable. You might want to do much more, e.g. write a more focused catch block. It's up to you to build on the foundation you've been given.

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

7 Comments

That makes sense @matt, part of the problem was "why not just provide nothing instead of _?" which made it seem like there was some special distinction when really it seems like _ and (nothing) are the same. Which still makes me wonder how/why Apple lets you accomplish the same thing two different ways...
@Shizam Because of other places where the _ is actually useful. You can use _ anywhere you can declare a variable. Why should catch blocks be the exception to the rule?
@Shizam But you already gave the answer. There is a distinction: "nothing" lets the error variable arrive into the catch block. The _, exactly as in a switch case, mops up the error and prevents it from entering the catch block. This is a catch block so minimal that it does absolutely nothing. That's what I said in my answer, I believe.
@Shizam It's not actually unexpected. It's very well documented! :) The error variable exists inside a catch block only if that catch block's pattern is completely empty.
@Shizam One more little thing; I've never used the automatic Swift 2.0 updater. I like to decline the automatic update, try to compile, fail, and fix all the problems myself. I've learned much more about Swift 2.0 by doing that!
|
2

If the variable declared before the catch block isn't actually used in the following block then Xcode will automatically convert this to an _ since it is not used. So in your example above, if jsonError wasn't actually used in the catch block, Xcode may automatically convert this to _. This isn't just for do {} catch {} but also things such as if let ... { }.

I think because it does this convert with other things too, like the if let ... {}, if they were to not put the _ in these places the code wouldn't actually work. Hence it does _ everywhere to be safe, even though in some places you may not actually need it.

2 Comments

This is the problem with opinion-based questions. They can only illicit opinion-based answers. This answer is marked as accepted based on comments following "I think..."...
@nhgrif There are two aspects to the question here "Why did it convert it this way?" and "What is the difference btw _ and (nothing)". While the former may lend itself to (some) speculation the latter doesn't and this clarifies that bit.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.