 # How to understand the Int Double conversion in Swift?

Extend the example in “The Swift Programming Language” (Swift 5.5) “Integer and Floating-Point Conversion”:

``````3 + 0.14 // allowed

let three = 3
let rest = 0.14

3 + rest // allowed
0.14 + three // compile error
three + 0.14 // compile error
``````

I don’t understand why the last two lines are taken as compile error. Can anyone help to explain a bit? Thanks.

The `+` operator takes two arguments of the same type, and the types of variables and constants are inferred considering only their initializations and not how they're later used. `rest` is inferred to have `Double` type, so `3 + rest` is only allowed if the literal `3` can have `Double` type. Similarly, `three` is inferred to have `Int` type, so `three + 0.14` is only allowed if the literal `0.14` can have `Int` type. But while `3` can have `Double` type (since integers are usually expressible as `Double`s), `0.14` cannot have `Int` type (since fractions are not expressible as `Int`s).

3 Likes

You might appreciate this read: Swift Literals - NSHipster

1 Like

There are two related things going on in the sample code: type inference (of variables) and coercion of literals to a type.

With type inference of variable declarations, the compiler uses the type(s) of the assigned value(s) to infer the variable's type.

``````let x: Double = 3.14
let y = x // <== y is inferred to be a Double because it has been assigned a value that is known to be of type Double
``````

Coercion of literals is the process of determining what type to give a literal (usually a number-like string of characters). For this, the compiler will use the variable declaration (such as `x` in my example above), the function to which the literal is being passed as a parameter, or other context that is available.

Now that we have this information, let's take your code line-by-line.

``````3 + 0.14
``````

In Swift, operators are functions. The `+` operator takes two parameters (its operands). All overloads of `+` that take numbers take numbers of the same type. The compiler determines that `0.14` is not expressing an `Int`, so it assigns it a type of `Double`. Now the compiler looks at `3`, knowing that it must have the same type as `0.14` to be valid for the `+` operator. As `3` can express a `Double`, the compiler performs the implicit conversion and `3` is given a type of `Double`.

``````let three = 3
``````

This is inferring the type of the literal and assigning that type to the variable `three`. The compiler prefers conversions to `Int` over conversions to `Double`. As `3` is parsable as an `Int`, the compiler implicitly converts the literal to an `Int`. As an `Int` is being assigned to `three`, the type of `three` will be `Int`. This line combines both literal coercion and type inference of variables.

``````let rest = 0.14
``````

This is the same as the previous line, except that `0.14` isn't parsable as `Int`, so the compiler parses it as a `Double`.

``````3 + rest
``````

As in the first line, the compiler knows that `rest` is of type `Double`, so it infers that `3` must be given the same type. As this is possible, the compiler goes ahead and does it.

``````0.14 + three
``````

As explained above, `0.14` can't be given a type of `Int`, and `three` is of type `Int`. As the `+` operator requires its operands to have the same type, the compiler produces an error.

``````three + 0.14
``````

Same as the previous, as you've only reversed the order of arguments.

2 Likes