This questions is really two things. First, is there a comprehensive Swift operator precedence and associativity table somewhere? In particular, here's a common pattern I run up against (in my case, because I use Marshal for object <-> dictionary conversions).
self.prettyStatus = (try? inObj.value(for: "order.prettyStatus")) ?? "Canceled"
try? is used here because sometimes that key is null or doesn't exist. In this case, it seems the nil-coalescing operator binds with higher precedence than
try?, and so I have to put parentheses around the
try expression above. This feels counterintuitive to me, and while I don't think this change could be made to the language now without breaking a lot of code, I am curious as to why the associativity works out this way. Was it deliberate, or just a consequence of how things worked out?
In a similar case, I am able to write this without the explicit parentheses (
try is used because it’s an error if that key is missing):
self.subtotal = try inObj.value(for: "order.subtotalCents") / Decimal(100)
In both cases, the type of the property on the left is enough for Swift to specialize the generic
inObj.value() call to return the right type. It seems
?? binds more tightly than
try?, which binds more tightly than
/. And the way the type inference works through all this is just magic (but I'm grateful it works as well as it does).
Can anyone shed some light on what's happening here, so that I may better understand it? TIA!