2014-10-04 3 views
0

Я понимаю, что в Swift, если я определяюIs 'x? .y' в Swift так же, как 'x?' а затем «.y»?

var opt:String? = "Optional" 

Я получаю сообщение об ошибке, если я попытаюсь

opt.isEmpty 

так opt имеет тип String?, который делает не имеет isEmpty метод. И я подумал, что я понял, что

opt?.isEmpty 

не вызывает ошибку, потому что opt? разворачивает (любой не- nil) opt, в результате чего String, который не имеет isEmpty метод. Но

opt? 

на своих собственных результатов в String? и не String.

Есть ?. другой оператор от ?, а затем .?


Попробуйте

(opt?).isEmpty 

и получить наводящую ошибку.

+0

Вопрос заключается в том, отличается ли 'opt? .isEmpty' от (грубо)' (opt?). IsEmpty' (это, безусловно, похоже), и если да, то что происходит, когда 'opt?' Оценивается на его независимо от того, что происходит, когда оно оценивается как часть необязательной цепочки. Очевидно, что «развернуть (если не« nil ») или оставить в покое (если« nil') »не будет адекватным определением'? ', Потому что это не так, как оно себя ведет. – orome

+0

Эффективное место для начала ответа будет ясным объяснением того, что именно 'opt?' * Собственный собственный имеет вообще * (есть ли у нас 'var opt: Type?' Или 'var opt: Type!'). – orome

+0

«Тип?» И «Тип!» - это аннотации типов *, которые отличаются от 'opt?' Или 'opt!'. Как объяснено ниже, 'opt?' Ничего не делает на своем собственном ". –

ответ

1

Но выбираете? по своим собственным результатам в String? а не строкой.

Да. В соответствии с справочной системой Swift, выражениями, выражениями Postfix, Optional-Chaining Expression:

Самостоятельно, постфикс? оператор просто возвращает значение своего аргумента как необязательный.

Так что положить ? сам по себе в конце опциона - это полный номер. Это не имеет никакого эффекта.

Is?. другой оператор? с последующим .?

Да. Более конкретно, ? имеет значение optional-chaining effect при использовании в любом «постфиксном выражении», в том числе, когда следуют () (вызов функции), . (членский доступ) и [] (подстрочный индекс).

+0

Таким образом, 'opt?' Также является необязательным цепочечным выражением, где операция (неявное) постфикса является личным. И '(x?). Y' отличается от' x? .y' по той простой причине, что только последнее является необязательным цепным выражением; первый - 'y' * применяется к результату * дополнительной цепочки. Если у меня есть это право, все имеет смысл и полностью согласуется. – orome

+0

Также: [вопрос здесь] (http://programmers.stackexchange.com/q/258012/28601), в который вы могли бы внести свой вклад. – orome

+0

И еще одно примечание для полноты: '?.'is * not * (как я прошу в конце OP) использовать другой оператор из'? 'и' .': «Существует одно предостережение к вышеприведенным правилам. Если предопределенный оператор'! 'или'? ' без пробелов слева, он рассматривается как постфиксный оператор, независимо от того, имеет ли он пробел справа. Чтобы использовать '?' в качестве оператора дополнительной цепочки, он не должен иметь пробелов слева. " – orome

2

Да opt?.isEmpty отличается от String? .Это называется optional chaining .С быстро Руководством по программированию:

Можно указать дополнительные цепочки, поставив знак вопроса после дополнительного значения, на котором вы хотите позвонить (?) свойство, метод или индекс , если необязательный параметр не равен нулю. Это очень похоже на отметку восклицательного знака (!) После необязательного значения, чтобы заставить разворачивать его значение. Основное различие заключается в том, что необязательная цепочка изящно выходит из строя, когда опция равна нулю, тогда как принудительная разворачиваемость запускает ошибку времени выполнения, когда опция равна нулю.

Это создает дополнительные, как вы думаете var opt: String?

Теперь

opt?.isEmpty //it will not crash if opt is nil 

такой же, как за исключением

opt!.isEmpty //it will crash if opt is nil 

если opt! является nil, чем он не будет врезаться в runtime.Optional сцепления используется для вызова длинных последовательностей необязательно без calling.Every дополнительного цепочка возвращается дополнительно, т. е. выбрать? возвращает необязательный разворачивает его, и если nil, чем не вызов isEmpty else, вызов isEmpty и reutns value. Также

(opt?).isEmpty 

Когда вы пишете выше заявление это только по желанию (не опция опционного) и он не разворачивать из-за скобки.Таким образом, ошибка показывает

$T2?? does not have a member named `isEmpty` 

разворачивать его использовать

(opt?)!.isEmpty 

он возвращает ложное

Edit: Для уточнения более

var o1 = opt? 
    var o2 = ((opt?)?) 

не делает ничего в своей собственной он просто присваивает то же значение o1, o2 i.e String ?. для разворота opt и o1, o2 оба они являются необязательными и нуждаются в одном ! операторах, чтобы развернуть его.

Также, пожалуйста, не понимайте между String? и opt? они оба разные, когда? используются после того, как какой-то тип в decleration это делает необязательным и когда ? используется после переменной opt используется для развёртки в необязательной цепочке и вернуть необязательное значение он возвращается

Extra Материал:

попробовать это более уточнить

(((opt?)?)!).isEmpty  //it will unwrap with single ! 
((((opt?)?)!)?).isEmpty //compiler will show suggestion to remove ? 

ниже заявление делает необязательным факультативных опционального

var opt:String??? = "Optional" 

разворачивать

opt!!!.isEmpty 

EDIT2

opt? всегда возвращают необязательный, но если opt определяется как строки! это implicit optional и opt? вернется optional(explicit). если opt уже необязательно opt? не будет делать ничего

От быстро руководства по программированию

Говоря иначе:

If the type you are trying to retrieve is not optional, it will become optional because of the optional chaining. 
If the type you are trying to retrieve is already optional, it will not become more optional because of the chaining. 

Поэтому:

If you try to retrieve an Int value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used. 
Similarly, if you try to retrieve an Int? value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used. 
+0

Это не вопрос. См. Комментарий выше. – orome

+0

@raxacoricofallapatorius неправильно понял вопрос. Ответил мой ответ. – codester

+0

Спасибо. Я до сих пор не совсем понимаю, что именно «opt?» Делает сам по себе, и почему 'opt? .isEmpty' не совпадает с' (opt?) !. isEmpty'. Я вижу, как в документации объясняется дополнительная цепочка, а также как обрабатывается «nil»; ничто из этого не должно быть частью ответа. – orome

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