Kwangle Kwangle - 1 year ago 66
Swift Question

Swift: Why does this valid expression fail when put in ternary form?

I've written an expression that finds the largest of two variables and returns true if it is equal to or above a limit variable. They are all integers.

if max(num1, num2) >= limit {
result = 3
} else {
result = 2

this works fine, but if I try to put it in the more compact ternary format it is rejected with: 'could not find an overload for '>=' that accepts the supplied arguments'.

max(num1, num2) >= limit ? result = 3 : result = 2

I've tried putting the conditional in various bracket configurations but it still fails. Any ideas?

Further experimentation reveals that the problem is related to the limit var being set as implicitly unwrapped variable, although this is set in the init block:

limit: Int!

init (num: Int) {
limit = num

Many thanks.

Answer Source

The problem here is precedence, it should "work" if you have written

 max(num1, num2) >= limit ? (result = 3) : (result = 2)
//                                         ^          ^

Note the precedence of each operator:

  • ?:: associativity right precedence 100 (higherThan: AssignmentPrecedence)
  • =: associativity right precedence 90

so a ? b : c = d will be evaluated as (a ? b : c) = d since the ternary conditional operator has higher precedence than assignment.

Here in max(num1, num2) >= limit ? result = 3 : result, the type of result = 3 is () and result is Int, so there is a type mismatch between the two arms and caused error.

(However I'm not sure why the message talks about >=, please check if your num1 and num2 are also Int.)

That said, it is very unconventional (i.e. bad style) to put an assignment inside a ?:, typically you want to write this instead:

result = max(num1, num2) >= limit ? 3 : 2
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download