Alexander Paul
Alexander Paul

Reputation: 51

Is my solution correct to the problem ? Memberwise and Custom Initializers

Make a Height struct with two variable properties, heightInInches and heightInCentimeters. Both should be of type Double.

Create two custom initializers. One initializer will take a Double argument that represents height in inches. The other initializer will take a Double argument that represents height in centimeters. Each initializer should take the passed in value and use it to set the property that corresponds to the unit of measurement passed in. It should then set the other property by calculating the right value from the passed in value. Hint: 1 inch = 2.54 centimeters.

struct Height{
    var heightInInches :Double=0.0
    var heightInCentimeters :Double=0.0

    init(inches:Double) {
        heightInInches=inches * 2.54
    }
    init(centimeters:Double) {
        heightInCentimeters=centimeters/2.54

    }


}
let inch = Height(inches:65)
print(inch.heightInInches)

let centi=Height(centimeters:65)
print(centi.heightInCentimeters)

If you use the initializer for inches to pass in a height of 65, the initializer should set heightInInches to 65 and heightInCentimeters to 165.1.

Upvotes: 2

Views: 661

Answers (2)

Crocobag
Crocobag

Reputation: 2340

I suggest you move the conversion into didSet{} methods. The problem here is that after it gets initialized, if you change heightInInches for instance, then heightInCentimeters won't change.

struct Height{
    var heightInInches :Double {
        didSet {
            // called each time heightInInches changes
            heightInCentimeters = heightInInches / 2.54
        }
    }
    var heightInCentimeters :Double {
        didSet {
            // idem
            heightInInches = heightInCentimeters * 2.54
        }
    }

    init(inches:Double) {
        heightInInches = inches
        heightInCentimeters = inches / 2.54
    }
    init(centimeters:Double) {
        heightInCentimeters = centimeters
        heightInInches = centimeters * 2.54
    }
}

Note that didSet is not called via init methods. You have to duplicate this conversion or to place it in another function that will be call in the init and the didSet.

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347184

Backup for a second and take each requirement in isolation

One initializer will take a Double argument that represents height in inches. The other initializer will take a Double argument that represents height in centimeters.

Each initializer should take the passed in value and use it to set the property that corresponds to the unit of measurement passed in.

Which might look something like...

init(inches:Double) {
    heightInInches = inches
}

init(centimeters:Double) {
    heightInCentimeters = centimeters
}

It should then set the other property by calculating the right value from the passed in value. Hint: 1 inch = 2.54 centimeters.

Which might look more like this...

init(inches:Double) {
    heightInInches = inches
    heightInCentimeters = inches * 2.54
}
init(centimeters:Double) {
    heightInInches = centimeters / 2.54
    heightInCentimeters = centimeters
}

This then allows you to set the properties as let and avoid all the issues with a mutating struct

struct Height{
    let heightInInches: Double
    let heightInCentimeters: Double

    init(inches:Double) {
        heightInInches = inches
        heightInCentimeters = inches * 2.54
    }
    init(centimeters:Double) {
        heightInInches = centimeters / 2.54
        heightInCentimeters = centimeters

    }
}

which is a lesson best left for another day ;)

Upvotes: 1

Related Questions