Giulio Crisanti
Giulio Crisanti

Reputation: 380

All values in a class 'nil' in swift

I recently encountered a strange issue with classes in swift.

Essentially, I'm writing a small program that tracks some basic information and does some calculations on some planets, mostly for practice really.

To go about this, I initially set up a class to store some basic properties. Next, I added a few planets, and finally gave some specific values to each planet. However, despite giving values, each planet's properties are still displayed as 'nil'. Here is an example of some of the code:

class Body {
    var distanceToSun:Float80 = 0.0
    var mass:Float80 = 0.0
    var radius:Float80 = 0.0
}

var Mercury:Body?
var Venus:Body?
var Earth:Body?

Mercury?.distanceToSun = 67790000
Mercury?.mass = 300000000000000000000000
Mercury?.radius = 2440

Venus?.distanceToSun = 108000000
Venus?.mass = (Mercury?.mass)! * 14.7
Venus?.radius = 6052

Earth?.distanceToSun = 147000000
Earth?.mass = (Venus?.mass)! * 1.266
Earth?.radius = 6378

print(Earth?.mass) // prints 'nil'
print(Mercury?.radius) // prints 'nil'
print(Mercury?.distanceToSun) // prints 'nil'

//etc etc

Am I missing something obvious here? Any help would be greatly appreciated. Thanks!!

Upvotes: 0

Views: 64

Answers (3)

vadian
vadian

Reputation: 285082

You have to initialize the planets with the () initializer and remove all that optional stuff

class Body {
  var distanceToSun:Float80 = 0.0
  var mass:Float80 = 0.0
  var radius:Float80 = 0.0
}

var Mercury = Body()
var Venus = Body()
var Earth = Body()

Mercury.distanceToSun = 67790000
Mercury.mass = 300000000000000000000000
Mercury.radius = 2440

Venus.distanceToSun = 108000000
Venus.mass = (Mercury.mass) * 14.7
Venus.radius = 6052

Earth.distanceToSun = 147000000
Earth.mass = (Venus.mass) * 1.266
Earth.radius = 6378

print(Earth.mass)
print(Mercury.radius)
print(Mercury.distanceToSun)

It might be more convenient to use a struct because you get the member wise initializer for free.

struct Body {
  var distanceToSun:Float80 = 0.0
  var mass:Float80 = 0.0
  var radius:Float80 = 0.0
}

var Mercury = Body(distanceToSun: 67790000, mass: 300000000000000000000000, radius: 2440)
var Venus = Body(distanceToSun: 108000000, mass: (Mercury.mass) * 14.7, radius: 6052)
var Earth = Body(distanceToSun: 147000000, mass: (Venus.mass) * 1.266, radius: 6378)

print(Earth.mass)
print(Mercury.radius)
print(Mercury.distanceToSun)

Upvotes: 0

AdamPro13
AdamPro13

Reputation: 7400

You never actually initialized the objects. Change to (I'd also make the variable names start with a lowercase letter):

var mercury = Body()
var venus = Body()
var earth = Body()

Upvotes: 1

Rob Napier
Rob Napier

Reputation: 299345

This is all as expected. Let's look at a single case:

var Mercury:Body?

So, Mercury is nil, since you never assigned it to anything. Then you execute:

Mercury?.distanceToSun = 67790000

This says "if Mercury is not nil, assign this value to distanceToSun." Since of course Mercury is nil, this does nothing.

I'm not clear why these are optionals at all. Just make them non-optional, and most of this will work as expected. Better yet, get rid of all the defaults and optionals, and just initialize things.

class Body {
    let distanceToSun:Float80
    let mass:Float80
    let radius:Float80
}

let mercury = Body(distanceToSun: 6779000, mass = 300000000000000000000000, radius = 2440)

Why would any of these be variables? Mercury is unlikely to change its mass significantly over the run of your program.

Upvotes: 4

Related Questions