Reputation: 3952
I understand the use of optionals enough to know when its necessary to unwrap an optional using the exclamation point. Why is it that the exclamation point isn't needed in a guard statement?
This code works and compiles but doesn't use exclamation points:
struct Blog{
var author:String?
var name: String?
}
func blogInfo2(blog:Blog?){
guard let blog = blog else {
print("Blog is nil")
return
}
guard let author = blog.author, name = blog.name else {
print("Author or name is nil")
return
}
print("BLOG:")
print(" Author: \(author)")
print(" name: \(name)")
}
This code also works if you do put the exclamation points:
struct Blog{
var author:String?
var name: String?
}
func blogInfo2(blog:Blog?){
guard let blog = blog! else {
print("Blog is nil")
return
}
guard let author = blog.author!, name = blog.name! else {
print("Author or name is nil")
return
}
print("BLOG:")
print(" Author: \(author)")
print(" name: \(name)")
}
Isn't this a little contradictory or can someone clearly explain why the exclamation point isn't needed?
Upvotes: 0
Views: 546
Reputation: 27226
I understand the use of optionals enough to know when its necessary to unwrap an optional using the exclamation point.
I have the feeling that you don't understand Swift Optionals enough if you make that assertion.
The contract behind an Optional is that it may or may not be nil; you don't know it and therefore you have to Unwrap it (like opening a box and see what's inside) before you can tell.
The box may be empty (nil Optional) or it may contain a value.
There are very few reasons to use the Forced Unwrap (!
). Very Few, and it's generally considered a bad practice in most (but not all) cases.
To continue the analogy, by force unwrapping stuff, you're saying there is something in this box, and I want you to trust me and don't check.
Knowing that an Empty box will crash your application, this is a very dangerous thing to do, considering Optionals were introduced in Swift to protect you from these sort of crashes to begin with.
The if let/guard let
statements basically peek inside the box and if there is something, they give it to you, but they also give you the chance to do something else in case the box is empty.
Xcode does force unwrapping when using IBOutlets because by design the contract is that those objects will be available by the time you can use them in your view controller, but unless you're 100% sure a value is not going to be nil
then it's almost always better (and future proof) to use a guard
statement (or an if
).
In my experience, even when you know for sure, it's still safer to toss a guard
and forget about the future problems that may arise.
Upvotes: 2
Reputation: 64002
guard let unwrapped = optional
is an Optional Binding (no link available directly to the correct book section, unfortunately). It safely tries to unwrap the value in the optional. If there is a value, the unwrap succeeds, and the value is assigned to the given name.
You should heavily favor the use of optional bindings, with either guard
or if
(the difference is the scope of the "unwrapped" name) over the use of forced unwrapping with !
. A failed force unwrap is a fatal error; your program will simply crash.
Upvotes: 4
Reputation: 66244
The exclamation "force" unwraps an optional. guard let
or if let
unwraps it without forcing anything, so no exclamation point is used.
Upvotes: 1