I've often written code like the following where I only want a variable unwrapped for a simple ternary expression.
subscript(key: String) -> Widget? {
get {
return self.wrappers[key]?.widget
}
set {
let wrapped: Wrapper<Widget>?
if let value = newValue {
wrapped = Wrapper(value)
} else {
wrapped = nil
}
self.wrappers[key] = wrapped
}
}
The getter looks great. The setter is a bunch of lines of incantation to do something simple. If I weren't against explicit unwrapping, I could have done this:
self.wrappers[key] = newValue == nil ? nil : Wrapper(newValue!)
Map is also available. I would argue it's not exactly intuitive, could make for ugly lines, and it doesn't work on other pattern matches.
self.wrappers[key] = newValue.map { Wrapper($0) }
So getting to the point: I would prefer something a little more concise and consistent with other conditional branches. What I would like to see is a way to unwrap inline for the duration of the true case or bind enum case values for the duration of the true case.
self.wrappers[key] = (let value = newValue) ? Wrapper(value) : nil
This could support case pattern matches too.
self.wrappers[key] = (case let .some(value) = newValue) ? Wrapper(value) : nil
let intVal = (case let .integer(value)) ? value : 0
let isLlama = (case let .animal(type, _) ? type == .llama : false
I'll be the first to say I'm not thrilled by the syntax, but at least it'd be consistent. Despite looking like an expression, if this were implemented it should probably not be able to be used elsewhere.
Anyone else run into this a lot? Have thoughts or better ideas?