Быстрое увеличение Int! не работает

Я понимаю, как работают опции, но это ставит меня в тупик. У меня есть переменная с именем num, и я хочу увеличить ее, поэтому я сделал следующее:

var num:Int! = 0
num++             //ERROR - Unary operator ++ cannot be applied to an operand of type Int!

Но по какой-то причине Swift не позволяет мне увеличить принудительно развернутый Int, хотя предполагается, что он должен рассматриваться как обычный Int с возможностью nil за кулисами. Итак, я попробовал следующее, и это сработало:

var num:Int! = 0
num = num + 1     //NO ERROR

Однако, основываясь на сообщении об ошибке, которое оно мне дало, я попробовал следующее, чтобы оператор приращения все еще работал:

var num:Int! = 0
num!++            //NO ERROR

Мой вопрос: почему первый бит кода ломается, а второй и третий - нет? Кроме того, поскольку num является Int!, разве я не могу относиться к нему как к обычному Int? Наконец, поскольку Int! должен рассматриваться как обычный Int, как я могу развернуть его в третьем примере? Спасибо.


person Adam Evans    schedule 01.08.2015    source источник
comment
Поскольку вы сразу инициализируете его 0, он не должен быть необязательным. Вы можете иметь var num = 0 без необходимости инициализаторов   -  person Jack    schedule 01.08.2015
comment
Спасибо за информацию, но независимо от того, почему мой код выше странный?   -  person Adam Evans    schedule 01.08.2015
comment
@JackWu: сделать его необязательным означает, что вы можете установить его на ноль позже, если у вас есть причина для этого.   -  person gnasher729    schedule 01.08.2015
comment
Постфиксный оператор принимает параметр inout, так что это, по сути, одна и та же проблема: not-compile">Передача неявно развернутой переменной в параметр inout не компилируется.   -  person Martin R    schedule 01.08.2015
comment
@ gnasher729 Я знаю, что делает необязательный параметр. Вопрос совершенно ясно выражает намерение, что num никогда не будет установлено на nil.   -  person Jack    schedule 01.08.2015
comment
@MartinR Это имеет смысл, но означает ли это, что бинарные операторы не принимают входные параметры, поскольку мой второй блок кода работает? Кажется странным, что унарные операторы не могут использовать опции, но могут их использовать.   -  person Adam Evans    schedule 01.08.2015
comment
@Aderis: Нет, бинарные операторы берут два операнда и возвращают результат. Это postfix func ++(inout x: Int) -> Int против func +(lhs: Int, rhs: Int) -> Int. – Но я не знаю, почему автоматическая распаковка не происходит с IUO.   -  person Martin R    schedule 01.08.2015


Ответы (2)


Эта ошибка возникает со всеми параметрами inout и должна рассматриваться как ошибка.

Обычный способ работы параметров inout заключается в том, что их геттер вызывается один раз, а их сеттер - по крайней мере один раз. В этом случае геттер возвращает Int!:

let num: Int! = 0
let num2 = num // is inferred to be of type Int!

поэтому подпись получателя/установщика не совпадает с ожидаемой функцией/оператором. Но компилятор должен неявно разворачивать значение, если оно присваивается Int или передается следующим образом:

var num3 = 0 // is of type Int
num3 = num // gets automatically unwrapped

// also with functions
func someFunc(i: Int) {}
someFunc(num) // gets automatically unwrapped

Примечание:

Почти такая же ошибка возникает, если вы хотите передать Int функции с параметром inout типа Int!. Но здесь очевидно, почему это не работает (логически): сеттер Int никогда не берет nil.

person Qbyte    schedule 01.08.2015

Вы используете неправильный тип Int!, используйте вместо него Int

person Andrii Liakh    schedule 01.08.2015
comment
Я использую его в ViewController, у которого нет метода init(), и вся моя инициализация выполняется в viewDidLoad, поэтому он должен быть каким-то необязательным, и я не хочу делать его Int?, потому что тогда я пришлось бы везде иметь дело со знаками вопроса, и оно всегда имеет значение после моего viewDidLoad - person Adam Evans; 01.08.2015
comment
выполните инициализацию в строке объявления var num = 0. Int — тип по умолчанию - person vadian; 01.08.2015
comment
Спасибо за информацию, но независимо от того, почему мой код с необязательным параметром странный? - person Adam Evans; 01.08.2015
comment
но ваша переменная инициализирована, почему вы должны использовать необязательно? И Int! не является обязательным, Int? не является обязательным. И в необязательном случае num!++ - правильный способ увеличить эту переменную - person Andrii Liakh; 01.08.2015
comment
Здесь не рассматривается реальная проблема, то есть почему ++ не работает на Int!. - person fabian789; 01.08.2015