A O
A O

Reputation: 5698

How to move property setting in Struct initialization into another method

So I have a struct, call DemoType, where I want the caller to initialize it with two properties-- however I also want to expose the ability to set the second property,

the problem is that before setting prop2, there is quite a lot of logic that needs to run first. This means that there is a lot of repeat lines of code, which I'm trying to reduce by keeping that logic in one place. I would like to keep it all in setProp2

struct DemoType {
    var prop1: String
    var prop2: String

    init?(p1:String, p2:String) {
        self.prop1 = p1
        let potentialFailure = true
        guard potentialFailure else { return nil }
        // Like 20 lines of logic here manipulating p2
        self.prop2 = p2
    }

    mutating func setProp2(_ p2:String) {
        let potentialFailure = true
        guard potentialFailure else { return }
        // Like 20 lines of logic here manipulating p2
        self.prop2 = p2
    }

}

So from a logical standpoint, I could just call setProp, and everything would be cool

struct DemoType {
    var prop1: String
    var prop2: String

    init?(p1:String, p2:String) {
        self.prop1 = p1
        self.setProp2(p2)
    }

    mutating func setProp2(_ p2:String) {
        let potentialFailure = true
        guard potentialFailure else { return }
        // Like 20 lines of logic here manipulating p2
        self.prop2 = p2
    }

}

Unfortunately, the compiler will complain that I have not initialized all of my properties in the init,

and also i want the init to be fallable, so it can return nil if certain checks fail, so I'm not sure how I would do that with this implementation, as I can make setProp2 just return, but then how do I make the caller (init) return nil?

I imagine what I'm trying to do must be possible, but I just don't know the syntax the compiler is looking for. Alternatively I could pull those 20 lines of logic out into it's own method and have both call it, that would be cleaner as well, but because both call self.prop2 at the end, I was hoping there would be a way to just have one place where self.prop2 is assigned

Upvotes: 2

Views: 37

Answers (1)

Kelvin Lau
Kelvin Lau

Reputation: 6771

The problem seems to be because your mutating set function can return early before setting the property. I suggest creating a function that configures prop2 and returns either the successfully configured prop, or a nil for an unsuccessful configuration:

func setProp2(_ prop2: String) -> Prop2? {
  // set up 
  return prop2
}

Now you can call setProp2 both from the initializer and from the mutating set function. This alleviates the duplicated code problem.

Upvotes: 2

Related Questions