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.