Which declaration to use in swift

18,469

Solution 1

The Float? is an optional. The Float! is an implicitly unwrapped optional. For details on the latter, see the Implicitly Unwrapped Optionals section of The Swift Programming Language: The Basics, which says:

[Optionals] indicate that a constant or variable is allowed to have “no value”. Optionals can be checked with an if statement to see if a value exists, and can be conditionally unwrapped with optional binding to access the optional’s value if it does exist.

Sometimes it is clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it is useful to remove the need to check and unwrap the optional’s value every time it is accessed, because it can be safely assumed to have a value all of the time.

These kinds of optionals are defined as implicitly unwrapped optionals. You write an implicitly unwrapped optional by placing an exclamation mark (String!) rather than a question mark (String?) after the type that you want to make optional.

Implicitly unwrapped optionals are useful when an optional’s value is confirmed to exist immediately after the optional is first defined and can definitely be assumed to exist at every point thereafter. The primary use of implicitly unwrapped optionals in Swift is during class initialization, as described in Unowned References and Implicitly Unwrapped Optional Properties.

An implicitly unwrapped optional is a normal optional behind the scenes, but can also be used like a nonoptional value, without the need to unwrap the optional value each time it is accessed.

You describe that value will be a class property. If this was a Float that you're always setting in the init method, then you wouldn't need to make it an optional at all, so you might use your second syntax. If it's a variable that might be nil or non-nil at any point, then you'd make it an optional (your third syntax). But if it's a variable that you cannot set in init, but once you set it, it would generally always have a value from that point on, might you lean towards the implicitly unwrapped optional (your fourth syntax).

Solution 2

You've got a lot more options then that! Just off the top of my head you could also do:

var value = Float(0)
lazy var value: Float = 1
var value = {0 + 0 as Float}()

Etc, etc. Anyway: I'll assume that this is for instance variables; that isn't clear from your question.

Let's talk about optionals first: you should (if possible) avoid optionals, unless you are dealing with a situation where a value can explicitly be missing; for instance a view that you only instantiate sometimes, or a delegate that isn't always set. In my opinion (and in the opinion of smarter people then me; see github's own Swift Style Guide) you should use implicitly unwrapped optionals (value: Float!) as little as possible. We see them frequently in Apple's APIs because those APIs are adopted from frameworks that were written in Obj-C, which uses nil differently. The only time something should be an implicitly unwrapped optional is when it can only be set after init, and when it will never be nil; the place that we see it most frequently is in views that are loaded from storyboard, since this happens just after a view controller is init'd.

For the other patterns: If you don't want to set an initial value, I think that initializing to zero is a good, clear pattern. It is certainly better then using an optional, unless you very specifically want to communicate that this value may not hold any value, at some point in the future.

If you're dealing with something heavier then a float (say an object that is expensive to instantiate) I prefer the lazy pattern, because if you never access the value until you assign to it it will never be instantiated. There are currently some compiler issues around this, at the moment (XCode 6.1.1), so it might be preferable to use optionals for the time being; lazy uses optionals behind the scenes, anyway.

Share:
18,469
Drakalex
Author by

Drakalex

French 21yo student who loves programming and making video games !

Updated on June 04, 2022

Comments

  • Drakalex
    Drakalex almost 2 years

    I really don't know how to declare my variables in Swift, I have four options :

    var value = 0.0 // I know this one declares value as a Double with the number 0.0
    var value: Float = 0.0 // This one declares value as a Float with the number 0.0
    var value: Float? // I really don't get the difference between this
    var value: Float! // and this, I just know that both of them are used to declare a variable without a value, am I right ?
    

    I just want to declare a float without attributing a value, what is the best way ?

  • pete
    pete over 3 years
    how do you do like "1.0f" when using without variables like in C++