Reputation: 5698
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
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