почему унарные и бинарные операторы имеют разные требования к параметрам?
Ну, это не унарный и бинарный вопрос. Есть унарные операторы, которые работают с Int!
. Например:
var i: Int! = 17
var j = -i
-
— унарный оператор, и он работает. Вопрос возвращается к проблеме inout
. Операторы префикса и постфикса ++
для Int
не работают с Int!
, поскольку переменная передается как inout
(поскольку ++
не только возвращает значение, но и изменяет исходную переменную). inout
требует точного соответствия типа.
Обратите внимание, что неявно развернутые опции по-прежнему являются необязательными.
var i: Int! = 17
var k = i // k has the type Int!
var m = i! // m has the type Int
Таким образом, передача неявно развернутого опционала в качестве переменной inout
, для которой требуется необязательный тип, не работает, потому что переменные inout
должны точно соответствовать ожидаемому типу, а Int
и Int!
— это два совершенно разных типа. Переменная должна быть либо явно развернута, либо вам нужно предоставить перегруженную функцию, которая принимает необязательный тип.
Вы можете спросить, почему Swift просто не разворачивает Int!
для вас и не вызывает ++
с Int
? Ну, ++
и изменяет переменную, и возвращает значение. Если бы Swift развернул Int!
и вызвал ++
с Int
, то тип возврата был бы Int
. Тогда у вас будут люди на StackOverflow, которые будут спрашивать: «Почему var i: Int! = 17; var j = i++
делает j
Int
вместо Int!
?». Чтобы сделать это правильно, ++
должно возвращать Int
, когда ему дается Int
, и возвращать Int!
, когда ему дается Int!
. Итак, что нужно в перегруженной функции.
Можно перегрузить ++
и сделать префиксные и постфиксные функции ++
для Int!
:
prefix func ++(inout x: Int!) -> Int! {
return ++x!
}
postfix func ++(inout x: Int!) -> Int! {
return x!++
}
var i: Int! = 17
var j = ++i
print("i = \(i), j = \(j)") // "i = 18, j = 18"
j = i++
print("i = \(i), j = \(j)") // "i = 19, j = 18"
Что касается того, почему дизайнеры Swift этого не сделали, только они знают, почему.
person
vacawama
schedule
01.08.2015