When I try unwrapping a var, I get an error

71 Views Asked by At

I'm trying to create a var without assigning a value when it's initialized. I'm new to swift, coming from Objective-c, and I'm having trouble using the wrapper/unwrapper. I have the following in my code:

var elapsedTime : NSTimeInterval!

self.elapsedTime -= (NSTimeInterval(hours) * 3600)

I get the following error at the second line:

Binary operator '-=' cannot be applied to operands of type 'NSTimeInterval!' and '(Double)'

What should I do to fix that, and why am I getting an error?

2

There are 2 best solutions below

5
On BEST ANSWER

It's a behavior specific to the implicitly unwrapped optional. The ! after the name of the type makes it an implictly unwrapped optional, for instance with NSTimeInterval!. The compiler will let you try and access the value inside the optional without checking for nil. If there is a nil there at runtime, your program will explode.

For some reason, -= can't be applied with the implicitly unwrapped optional on the left. NSTimeInterval is a typealias for Double, so I'm going to use a simple example.

var time = 0.0
var dangerousTime: Double! = 15.0
time -= dangerousTime // works fine
dangerousTime = dangerousTime - time // works fine
dangerousTime -= time // errors out

Implicitly unwrapped optionals are dangerous and you should avoid using them. This will probably fix your problem anyway. A few possible ways to go from here:

In Swift, you don't need an Optional to declare a variable without initialization. The compiler just won't let you use it until you've assigned it an initial value.

var time: Double
var foo = time + 5 // error
time = 4.0
foo = time + 5 // success

What you may want is a regular old Optional and a safe syntax for using the Optional.

var maybeTime: Double?
if let time = maybeTime {
    maybeTime = time - 42
}
0
On

You may have run into a compiler bug.

elapsedTime is declared as an Optional, which means that it may have a value, like zero, or it may have no value.

The -= operator only has meaning when elapsedTime has a value.

If you want to handle the case where elapsedTime has no value, you can do something like this:

if let elapsedTime = self.elapsedTime {
    self.elapsedTime = elapsedTime - (NSTimeInterval(hours) * 3600)
}
else {
    // self.elapsedTime has no value.  What do you want to do?
}

If you just want to assume that self.elapsedTime always has a value, you can do this:

    let elapsedTime : NSTimeInterval = self.elapsedTime
    self.elapsedTime = elapsedTime - (NSTimeInterval(hours) * 3600)

That will compile, but it will crash at runtime if self.elapsedTime has no value.

It might be a compiler bug because -= should perhaps be equivalent to the last example, but instead produces a compiler error.