Reputation: 8608
I'm having a bit of a hard time wrapping my head around optionals and why they are beneficial.
First off, are these two code block essentially equivalent?
Swift:
if let unwrappedName = p.name {
var greeting = “Hello “ + unwrappedName
} else {
var greeting = “Hello stranger”
}
Objective-C:
NSString *greeting;
if (p.name) {
greeting = [NSString stringWithFormat:@"Hello %@", p.name];
} else {
greeting = @"Hello stranger"
}
Second, this is coming from the Swift iBook, I don't get any errors on these but what exactly is the difference between them??
1.
let optionalSquare: Square? = Square(sideLength: 10, name: "Optional Square")
let sideLength = optionalSquare?.numberOfSides
2.
let optionalSquare: Square! = Square(sideLength: 10, name: "Optional Square")
let sideLength = optionalSquare?.numberOfSides
3.
let optionalSquare: Square? = Square(sideLength: 10, name: "Optional Square")
let sideLength = optionalSquare!.numberOfSides
Upvotes: 3
Views: 728
Reputation: 1252
Yes, optional types are pretty similar for reference types to Objective-C references. The key difference is that non optional type can never be "nil". If the type of returned a method you are calling is Object?, you are forced to unwrap it before using it. It is clear that the response can be "empty" and the compiler will force you to handle that.
If the type is not optional then you never need to check if it is nil before using. In addition, Optional work with value types like Int. You don't need to remember if the empty value is 0 or -1 or some other magic value.
You should use optional pretty much anytime you are thinking about using a magic sentinel value that means the absence of something, ie 0, -1, nil, empty list, empty string, etc. It not hard to remember what should be checked but it is easy to forget. With optional, you do not need to "double check" its not nil, even though it "should not be nil but maybe it is". Instead, of return -1 as an index of an object that was not found return Int?. Instead of throwing an exception, when a file is not found you can pass a an optional object.
Compare with optionals:
if let mapleSyrup = shoppingList.removeAtIndex(3) {
print "Bought /(mapleSyrup)"
}
To without optionals and not perfectly clear documentation:
var mapleSyrup = shoppingList.removeAtIndex(3)
if mapleSyrup != nil && mapleSyrup.isEmpty {
print "Bought /(mapleSyrup)"
}
The second question is answered well in the swift ibook here.
let optionalSquare: Square! = Square(sideLength: 10, name: "Optional Square")
Lets you use optionalSquare as if it was a normal variable and doesn't need to be unwrapped first.
let sideLength = optionalSquare!.numberOfSides
If you know optionalSquare
has a value, you can force to be unwrapped and used with !
.
This article starts with some great information on the problems with nil and the benefits of optional types.
Upvotes: 2