Swift If Case Let
source link: https://useyourloaf.com/blog/swift-if-case-let/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Swift If Case Let
The Swift If-Case-Let syntax is a convenient shortcut to avoid a full switch statement when you only want to match a single case. The syntax always seems backwards to me so here’s a reminder of how to use it.
Case Let - A Recap
I’m using the Swift Result
type to capture the results of a throwing expression. In this case, loading data from a file:
let result = Result { try Data(contentsOf: url) }
// result is of type Result<Data, Error>
The Result
type is an enum with a success and failure case both of which have an associated value. In my example, I would typically switch on the result:
switch result {
case .success(let data):
completion(data)
case .failure(let error):
print(error)
}
The let binds the associated value to a variable that we can use in the body of the case. We can also write these as case let
:
switch result {
case let .success(data):
completion(data)
case let .failure(error):
print(error)
}
We can also add a where clause to further filter the matching cases:
case let .success(data) where data.count > 100:
The case let syntax is not restricted to switch
statements. We can rewrite the switch as a series of if-case-let
statements if we want:
// if statement
if case let .success(data) = result { ... }
// if statement - alternate form
if case .success(let data) = result { ... }
// if statement with extra condition
if case let .success(data) = result, data.count > 100 { ... }
Note that the value we were switching on (result
) now becomes an initializer for the case statement. The last example written as a guard
statement:
// guard statement
guard case let .success(data) = result, data.count > 100 else {
return
}
Finally, here’s an example of a for-in
loop:
// for-in loop
for case let score in scores where score > 4 { ... }
Replacing A Switch With If Case Let
A switch
statement is fine when I have something to do for all (or most) of the cases. Here’s an example where I only care about the failure case. I’m encoding some model data and then writing it to a property list file:
let result = PropertyListEncoder.encode(countries)
.flatMap { Data.write($0, to: url) }
The Data.write
method is an extension I added on Data
that converts the throwing data.write(to:)
method to return a result of type Result<void,Error>
. It either succeeds, returning void
, or fails with an error. Switching over the result in this case is annoying:
switch result {
case .success():
// Nothing to do here
case .failure(let error):
// Handle error
print(error)
}
Using the case-if-let
syntax to replace the switch
statement:
if case let .failure(error) = result {
// Handle error
print(error)
}
Or using the alternate version which I find slightly easier to remember as it’s closer to the original switch
syntax:
if case .failure(let error) = result {
// Handle error
print(error)
}
I still find using the result
value as the initializer for the case-let confusing but I prefer it over the more verbose switch
version. What do you think? Do you have a favorite use for case let
?
Never Miss A Post
Sign up to get my iOS posts and news direct to your inbox and I'll also send you a PDF of my WWDC Viewing Guide
Unsubscribe at any time. See privacy policy.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK