1

I'm looking for a way to improve this pattern of code:

struct Struct {
    let i: Int

    init?(i: Int?) {
        guard let unwrappedI = i else { return nil }
        self.i = unwrappedI
    }
}

It'd be nice to remove the unwrappedI temporary variable. Any suggestions?

Alexander
  • 59,041
  • 12
  • 98
  • 151

2 Answers2

3

I would have said:

struct Struct {
    let i: Int

    init?(i: Int?) {
        if i == nil {return nil}
        self.i = i!
    }
}

I think that captures your initial desire to exit early and avoids the if/else you were trying to avoid, with no intermediate variable. To unwrap i, just unwrap it! No need for if let or guard let or any of that fancy stuff.

(On the other hand, I have to ask: if passing nil to the initializer is considered failure, why offer to accept an Optional in the first place?)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • The real world application is more complex than that, It's actually an optional local var that eventually needs to be unwrapped so that the optionality is isolated solely to the initializer – Alexander Jan 03 '17 at 03:13
  • I thought that might the case. :) – matt Jan 03 '17 at 03:22
  • Actually, while I'm here, I may as well check to make sure my design isn't totally garbage. I'm trying to parse a set of "chunks" of data from a [RIFF file ](http://www.johnloomis.org/cpe102/asgn/asgn1/riff.html) (the container format that other formats like `wav`, `ani` use). A valid file requires a certain set of chunks to be present, but they can come in any order. Thus those variable are optional while in the making, but should ultimately be checked, and assigned to non optional properties of the newly init'ed struct – Alexander Jan 03 '17 at 03:23
  • The best I could do was to duplicate the ivars as locals (as optionals) that are unwrapped after the parsing loop and are then assigned to the ivars (else return nil). Does that sound sensible? How would you do it? – Alexander Jan 03 '17 at 03:25
  • Yes, I think I see. So at the end you just run thru all of them and fail if any of them is nil. It would be nice to reduce that to looping thru a list but I can't think how to do it. Let's not let the desire for elegance get in the way just doing the job! – matt Jan 03 '17 at 03:58
  • Yeah I ended up just making an inner struct, akin to a factory, with all optional vars. I initialize that, then I pass it into the init of the real struct, which unwraps or returns nil – Alexander Jan 03 '17 at 04:02
  • Yes, I thought of that too. – matt Jan 03 '17 at 04:11
1

Well I was sure overthinking this... I need to sleep.

struct Struct {
    let i: Int

    init?(i: Int?) {
        if let i = i { self.i = i }
        else { return nil }
    }
}
Alexander
  • 59,041
  • 12
  • 98
  • 151