Thoughts? Preferences? For the context behind this, see this post, and the screenshots in particular.
Option 1:
extension Array { /// Return last element for array that is guaranteed /// to have at least one element public var lastOrDie: Element { assert(!self.isEmpty, "Array is guaranteed nonempty") let finalIndex = self.index(before: self.endIndex) return self[finalIndex] } }
Option 2:
extension Array { /// Return last element for array that is guaranteed /// to have at least one element public var lastOrDie: Element { guard let final = self.last else { fatalError("Failed to retrieve final array element") } return final } }
Option 3:
extension Array { /// Return last element for array that is guaranteed /// to have at least one element public var lastOrDie: Element { return self.last! // yes that's an exclamation point } }
Option 4:
array.last!
Option 5:
// postfix operators cannot begin with either a // question mark or an exclamation mark. postfix operator .!!! extension Optional { /// "This unwrap is intentional" operator. /// G. Paltrow: "Conscious Unwrapping" /// Courtesy of: http://twitter.com/lapcatsoftware/status/856902513303449601 public static postfix func .!!!(lhs: Optional) -> Wrapped { return lhs! } }
Option 6:
We need the !! operator for documenting force-unwraps pic.twitter.com/FBlwOsKvJL
— Airspeed Velocity (@AirspeedSwift) April 25, 2017
6 Comments
I’m not sure about my preferences, but for those who know Swift’s conventions,
Array#last!
feels like “lastOrDie” already. I think a function or computed property that just delegates to “last!” would be better off using the exclamation point explicitly at the call-site as opposed to being wrapped/redefined in the target.I like #2. It’s explicit in what you’re doing, and I think it might be easy to miss the bang (!) at the end of the self.last! unless you’re looking for it.
foo.last!
Option 4 obviously: that’s Swift.
I’d use #4 in this case. For chaining, I might consider an unwrapper function to make it more clear in debugging *which* optional killed the run, but for a single access like this, it’s a non-issue.
I agree with everybody who said option 4. It’s already “last or die”. Why create a function that does the same thing. Option 1, by the way, is brain dead. Yes it prints a pretty message in a debug build, but in a debug build, you are likely to be in the debugger when it happens anyway.