Небольшой вопрос о необязательном цепочке в Swift

Я запускаю эти коды на игровой площадке, но получаю ошибку компиляции с

a.b.b = 3

но он хорошо работает на следующей строке. В чем разница между этими двумя? Когда я должен использовать '!' явно и когда это не нужно?

Вот коды:

class A {
    var a = 1
    var b = B()
}

class B {
    var b = 2
}

var a:A! = A()

a.b.b = 3 // will get a compile error
print(a.b.b) // runs well, print 2
a?.b.b = 3 // runs well
print(a.b.b) // runs well, print 3


person richar lee    schedule 06.03.2020    source источник
comment
Ваш код работает нормально. Какую ошибку вы получаете?   -  person Alladinian    schedule 06.03.2020
comment
Проблема, с которой вы, вероятно, сталкиваетесь, связана с проблемами в игровых площадках. Если вы скомпилируете это в другом месте, он будет работать нормально. Тем не менее, вы почти наверняка не должны использовать неявно развернутый необязательный параметр. Они используются для решения некоторых проблем с поздней инициализацией, а в некоторых случаях используются для решения неаннотированных мостов Objective-C. Ситуация, которую вы описали здесь, почти наверняка не будет их правильным использованием (я не знаю ни одного случая, когда они подходят в качестве локальной переменной).   -  person Rob Napier    schedule 06.03.2020
comment
В вашем коде ни восклицательный знак, ни сама аннотация типа не нужны. Вы делаете это еще хуже: вы аннотируете необязательный как (неявно развернутый) необязательный. Избегайте опционов, насколько это возможно. И аннотируйте типы, только если компилятор просит вас это сделать.   -  person vadian    schedule 06.03.2020
comment
@Alladinian, может быть, это просто проблема на детской площадке. Я думаю, что они одинаковы, поэтому я путаюсь, когда встречаю ошибку. Спасибо за ответ.   -  person richar lee    schedule 07.03.2020
comment
@RobNapier Спасибо за ответ. Кажется, проблема на детской площадке меня смущает.   -  person richar lee    schedule 07.03.2020
comment
@vadian Спасибо за ответ. Кажется, проблема на детской площадке меня смущает.   -  person richar lee    schedule 07.03.2020


Ответы (1)


Добро пожаловать в Stackoverflow. Давайте попробуем ответить на ваши вопросы один за другим.

В чем разница между этими двумя? a.b.b = 3 и print(a.b.b)

Если это то, что вы имеете в виду, первый вызывает ошибку на Playground,

выражение не удалось разобрать, неизвестная ошибка

тогда на самом деле нет никакой разницы. Но если вы хотите знать, почему это происходит, это должно быть проблемой Playground. Потому что это выражение не должно вызывать ошибку времени компиляции в Xcode (проекте).

Чтобы решить эту проблему в Playground, вам нужно разбить выражение, например:

let bOfA = a.b
bOfA.b = 3

Вуаля! Проблема решена!

Также эта проблема может быть как-то связана с ошибкой Xcode:

Компилятор не может проверить тип этого выражения за разумное время; попробуйте разбить выражение на отдельные подвыражения


Когда я должен использовать '!' явно и когда это не нужно?

Вы используете этот !, если вы уверены, что ваш объект имеет значение. ! автоматически разворачивает объект, не проверяя, нулевой он или нет.

Когда не надо? Ну, насколько это возможно, вам не следует практиковать принудительное развертывание. Прочтите о вариантах безопасного развертывания для получения дополнительной информации. Есть много ресурсов об этом.

  1. Безопасная распаковка оптических строк и целых чисел
  2. https://learnappmaking.com/swift-Options-how-to/
  3. https://forums.developer.apple.com/thread/45469
person Glenn Posadas    schedule 06.03.2020
comment
Спасибо за это. Больше всего меня смутил первый ответ. Так что проблема с детской площадкой. И другие ответы тоже очень полезны. Большое спасибо - person richar lee; 07.03.2020