Я попытался добавить литерал Int
и Float
в Swift, и он скомпилировался без ошибок:
var sum = 4 + 5.0 // sum is assigned with value 9.0 and type Double
Но когда я попытался сделать то же самое с переменными Int
и Float
, я получил ошибку времени компиляции, и мне пришлось привести любой один операнд к типу другого, чтобы он работал:
var i: Int = 4
var f:Float = 5.0
var sum = i + f // Binary operator '+' cannot be applied to operands of type 'Int' and 'Float'
Почему так происходит? Это как-то связано с безопасностью типов?
Итак, чтобы соблюдать явно указанные аннотации типов, компилятор просит нас явным образом привести переменные к типу, верно?
Да это верно.
Если вы хотите двойной результат:
let i: Int = 4
let f: Float = 5.0
let sum = Double(i) + Double(f)
print("This is the sum:", sum)
Если вы хотите результат Int:
let i: Int = 4
let f: Float = 5.0
let sum = i + Int(f)
print("This is the sum:", sum)
Да, я знал об этом. Но я хотел знать, почему это предупреждение не генерировалось при использовании необработанных литералов. Ответ @Suyash Medhavi развеял мои сомнения.
В документе на Swift.org говорится:
Type inference is particularly useful when you declare a constant or variable with an initial value. This is often done by assigning a literal value (or literal) to the constant or variable at the point that you declare it. (A literal value is a value that appears directly in your source code, such as 42 and 3.14159 in the examples below.)
For example, if you assign a literal value of 42 to a new constant without saying what type it is, Swift infers that you want the constant to be an Int, because you have initialized it with a number that looks like an integer:
let meaningOfLife = 42 // meaningOfLife is inferred to be of type Int
Likewise, if you don’t specify a type for a floating-point literal, Swift infers that you want to create a Double:
let pi = 3.14159 // pi is inferred to be of type Double Swift always
chooses Double (rather than Float) when inferring the type of floating-point numbers.
If you combine integer and floating-point literals in an expression, a type of Double will be inferred from the context:
> let anotherPi = 3 + 0.14159 // anotherPi is also inferred to be of
type Double The literal value of 3 has no explicit type in and of itself, and so an appropriate output type of Double is inferred from the presence of a floating-point literal as part of the addition.
Вопрос больше о другом случае, когда был задан тип переменной.
В случае var sum = 4 + 5.0
компилятор автоматически преобразует 4 в число с плавающей запятой, поскольку именно это требуется для выполнения операции.
То же самое произойдет, если вы напишете var x: Float = 4
. 4 автоматически преобразуется в число с плавающей запятой.
Во втором случае, поскольку вы явно определили тип переменной, компилятор не может изменить его в соответствии с требованием.
Для решения посмотрите ответ @Fabio
Что вы ожидали? Вы явно определили типы каждой переменной, и чтобы компилятор заработал, ему пришлось бы переопределить одно из ваших объявлений типа, а это было бы намного хуже, не так ли?