Home > Enterprise >  Ambiguous use of operator '<' when comparing Doubles and Integers in Swift
Ambiguous use of operator '<' when comparing Doubles and Integers in Swift

Time:11-02

Why does swift behave so weird when comparing Doubles and Integers?

Consider the following code for repl/playground:

12>12.0        //false 

13 > 12.0        //true
13.0 > 12        //true

13 >= 12.0        //true
13 <= 12.0        //false

12.0 < 13        //Error: Ambiguous  use of operator '<'
12 < 13.0       //Error: Ambiguous  use of operator '<'

What exactly is Ambiguous in the use of operator here?

The debug console output is not especially helpful either:

error: ambiguous use of operator '<'
12 < 13.0
   ^

Foundation.RunLoop:18:32: note: found this candidate
            public static func < (lhs: RunLoop.SchedulerTimeType.Stride, rhs: RunLoop.SchedulerTimeType.Stride) -> Bool
                               ^

Foundation.Decimal:4:24: note: found this candidate
    public static func < (lhs: Decimal, rhs: Decimal) -> Bool
                       ^

Foundation.OperationQueue:18:32: note: found this candidate
            public static func < (lhs: OperationQueue.SchedulerTimeType.Stride, rhs: OperationQueue.SchedulerTimeType.Stride) -> Bool
                               ^

Dispatch.DispatchQueue:22:32: note: found this candidate
            public static func < (lhs: DispatchQueue.SchedulerTimeType.Stride, rhs: DispatchQueue.SchedulerTimeType.Stride) -> Bool

UPD: Just to clarify, I know that I can cast values explicitly.

The question is why exactly does the language behave this way and was is it designed to behave this way with < operator?

CodePudding user response:

I think operators >, >=, =, != were implemented by Swift's cast mechanism to compare. Operator <, == are two special operators which must be of the same type to compare.

I found a Swift Document, which has some information about it. Compare

CodePudding user response:

The first thing to note is you are not comparing Doubles to Ints. All of your examples compare two literals and I expect that Swift is inferring the types to be Double always. You can verify this with the following

let a: Int = 12
a > 12.0          // Error: Binary operator > cannot be applied to Int and Double

The second thing to note is that the problem goes away if you do not import Foundation.

What is actually happening is that Foundation introduces several overloads for < in order to make a number of Foundation types conform to Comparable and the compiler no longer knows which type to infer when compiling comparisons of literals (it must also be making these types conform to ExpressibleByFloatliteral and ExpressibleByIntegerLiteral) .

The reason that it is only for < is probably due to the fact that you only need to implement that operator to conform to Comparable and there are default implementations for the other comparison operators in an extension to the protocol.

  • Related