2015-03-14 2 views
3

У меня есть строка var oneString: String! и позже в методе, когда я хочу, чтобы сцепить строку oneString я должен сделать это:Почему я должен явно развернуть мою строку в этом случае?

oneString! += anyString 

Если я не добавить ! я получаю сообщение об ошибке 'String!' is not identical to 'CGFloat'

Если я инициализирую свою строку var oneString = "" У меня нет этой проблемы. Зачем? Почему мне нужно разворачивать oneString, в то время как я прямо сказал, что это будет не ноль, когда я объявлю это?

+1

Я думал, что этот вопрос с ответом Антона поможет вам понять, что происходит за кулисами http: // stackoverflow.ком/вопросы/24018327/что-делает-ан-восклицательный знак среднеквадратичных-в-быстрым язык? RQ = 1 –

ответ

3

Причина в том, что Foo, Foo? и Foo! являются различными типами в Swift.

Есть определенные операторы, предварительно определенные для вас «из коробки», которые обеспечивают большую прозрачность между Foo и Foo!, но все же эти типы не совпадают.

Когда дело доходит до строки, оператор

func += (inout left: String!, right: String) 

... просто не определен.

Если вы объявляете его как:

func += (inout left: String!, right: String) { 
    left = left + right 
} 

... тогда ваш код должен собрать так, как вам это нравится, то есть:

oneString! += anyString 
6

Почему мне нужно разворачивать oneString в то время как я прямо сказал, что это будет не ноль, когда я это объявлю?

Вы неправильно поняли, что такое var oneString: String!. Это не значит, что oneString не будет ник. Если вы объявите тип var oneString: String, , то вы объявляете тип, который не может быть равен нулю.

Тип String! - это «неявно разворачиваемый вариант». То есть, это необязательно, так же, как String?, но тот, который претендует быть необязательным иногда. В основном для целей чтения - вам не нужно явно разворачивать его, чтобы получить значение. Недостаток, если он когда-либо ник (и это полностью может быть), ваш код будет ловушку и прервать.

Но этот притворный для не-факультативно только до сих пор. Вы не можете передать String! функции inout, если этот аргумент не является необязательным. Отсюда и ваша проблема.

Ответ Антона полностью верен в том, почему он не будет работать, и предложенная им перегрузка оператора заставит ваш код скомпилировать. Но это не правильное решение - вместо этого вы должны избегать использования неявно-развернутых опций, поскольку они являются подпружиненными deathtraps и только для использования в определенных обстоятельствах (наиболее распространенное из них с элементами управления Cocoa UI). 999 раз из 1000 вам было бы лучше с обычным дополнительным или необязательным

Смежные вопросы