3

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
random
  • 8,568
  • 12
  • 50
  • 85
  • 1
    try to imagine the optional (`?`) as a variable which you do not no anything about it. you don't know whether it is `nil` or not, therefore before you unwrap it, your have to check, because unwrapping a `nil` will cause crash. if it is not optional (`!`) you can assume automatically that is not `nil` in spite of you can set it by `nil`, but it is not the expected value... and of course you need to follow this logic when you implement your own functions in _Swift_. – holex Jun 11 '14 at 15:58
  • I do not understand the sense of using "let" in this example. If it would be "var" then the optional makes sense because it could change to nil. But a "let" which is directly assigned can not become nil. Hence, making optional is obsolete... So, at which point am I wrong? – Jens Wirth Jun 12 '14 at 11:26
  • @jewirth I think that is what was confusing me as well and this example is pulled from Apple *Swift* book. I think in practicality you would not want a `let` to be optional. Can someone confirm? – random Jun 12 '14 at 14:55
  • 1
    @jewirth it could be nil despite being constant (let) if you get the result from a method that returns an optional, e.g.: `let optionalSquare:Square? = user.askForPreferredShape()`. Maybe user does not have a preferred shape and that method returns nil. – Taum Jun 20 '14 at 19:45

1 Answers1

2

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.

sanz
  • 1,232
  • 1
  • 9
  • 17
  • 1
    So is this `let optionalSquare: Square!..` the same as doing this `let optionalSquare: Square..`?? I don't understand if you are instantiating an object Square, why would it ever be `nil`? I can see the benefit in return types from method calls. – random Jun 11 '14 at 15:45
  • 2
    @random if you know it will never be nil, don't use an optional :) Optionals are for when you *don't* know whether it'll be nil – Jiaaro Jun 11 '14 at 15:47
  • 2
    @random Don't worry too much about implicitly unwrapped optional values, ie `impSquare: Square!`. Read the iBooks link about it, but you are typically not going to use it. Here one case when you would use it: http://stackoverflow.com/questions/24006975/why-create-implicitly-unwrapped-optionals – sanz Jun 11 '14 at 15:54
  • @Jiaaro I wouldn't make it an optional if I knew it was never going to be nil, who would do such a thing! O.o I've been developing in obj-c for years and never had such a big problem dealing with nil. It seems that if you design your code right and are an adept programmer, dealing with a nil variable isn't that big a deal. – random Jun 11 '14 at 17:00
  • @tony Thanks for the link to that post, that helped a lot. I guess what I was looking for was a concrete example of when an optional is best used. – random Jun 11 '14 at 17:01
  • 1
    The link in the comments is just for implicitly unwrapped optional values which probably will not be common. It easy to come up with many concrete cases Optionals will be used. Adding some more information about how its used. – sanz Jun 11 '14 at 17:11
  • @tony Would you mind updating your answer throwing in an example of where you would want to use an optional?? – random Jun 12 '14 at 14:56
  • "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" were my examples. Didn't see the value of writing a method to search a list just to show a change in the method signature. What part is still confusing the syntax of writing it or the situations when to use it? – sanz Jun 12 '14 at 15:27
  • @sanz I think I am getting it, it's more the conceptual side of when to use it. The syntax isn't a problem. I just want to make sure I use them properly from the start – random Jun 13 '14 at 13:28