Распаковка опционально (Swift Playground) - PullRequest
0 голосов
/ 15 января 2019

Простой вопрос для вас о развертывании опций.

Я прочитал и видел несколько примеров распаковки, как показано ниже

var strArray: [String]?
strArray = ["John", "Stacy", "Stephanie" ]

if let forSureNames = strArray{
   for name in forSureNames{
      print("\(name)")
   }
} else{
    print("Failed unwrapping")
}

Однако, мой вопрос для if let forSureNames = strArray{ ...

При вводе синтаксиса, подобного C ++ (и из некоторых быстрых примеров), добавление скобок

if (let forSureNames = strArray){

Дает коды ошибок:

'()' is not convertible to 'Bool'

error: MyPlayground.playground:13:4: error: expected expression in list of expressions
if(let forSureName = strArrays){
   ^
error: MyPlayground.playground:13:4: error: expected '{' after 'if' condition
if(let forSureName = strArrays){
   ^

Может кто-нибудь помочь объяснить разницу?

Редактировать Первый раз я задал вопрос о переполнении стека, и обратная связь потрясающая. Я пытался использовать стиль кодирования, похожий на C ++, из-за моей привычки к легкому переходу. Тем не менее, вы, ребята, дали понять, что это неправильный подход. Спасибо за новый и технический взгляд на распаковку. Ура!

Ответы [ 4 ]

0 голосов
/ 15 января 2019

Может кто-нибудь помочь объяснить разницу?

Разница в том, что Swift не является C ++. Хотя они во многом похожи, они имеют разные грамматики. Грамматика определяет (частично) синтаксис языка.

В C ++ оператор if является частью оператора выбора production в грамматике:

Селектор-оператор:

if ( условие ) оператор

if ( условие ) оператор else оператор

switch ( условие ) оператор

Таким образом, скобки вокруг условия оператора if являются частью оператора if, а not частью условия.

В Swift оператор if является единственным производным оператора if-10 * * производство в грамматике:

оператор if if блок кода списка условий else-условие opt

Обратите внимание, что в производстве if-оператор нет скобок. Поэтому, если необходимо заключить в скобки, они должны быть частью производства condition-list . Вот как список условий определяется :

список условий → условие | условие , список условий

условие → выражение | наличие-условие | кейс-условие | опциональное-связывающее условие

Таким образом, список условий - это одно или несколько условий s, разделенных запятыми. Если вы щелкнете по каждой из четырех альтернатив в условии , вы обнаружите, что условие доступности должно начинаться с токена #availability, case-условие должен начинаться с токена case, а необязательное условие привязки должен начинаться либо с токена let, либо с токена var. Ни одно из этих трех произведений не может начинаться с маркера в скобках.

Единственным производством условия , которое может начинаться с токена (, является производство выражения , а в выражении производство не может иметь токен let после токена (.

0 голосов
/ 15 января 2019

Как вы знаете, () может использоваться для окружения выражения, и это не повлияет на оценку этого выражения, и вы спрашиваете: "Почему я не могу сделать то же самое с let forSureNames = strArray?" Правильно?

Это потому, что let forSureNames = strArray не является выражением. Вы неправильно анализируете это утверждение. Слово let является частью оператора if let.

Вы путаете операторы if let с операторами if в стиле C, где после if всегда есть выражение, которое оценивается как Bool. if let просто так не работает. Он принимает форму:

if let <identifier> = <expression> { }

, где expression должен соответствовать необязательному типу. Так что ставить () вокруг let <identifier> = <expression> бессмысленно. Вы можете поставить () вокруг strArray, потому что , что - это выражение, но я не вижу в этом смысла.

0 голосов
/ 15 января 2019

Swift сильно отличается от C ++, поэтому не стоит удивляться, что синтаксис C ++ не работает в Swift.

Существует два типа операторов if в Swift: тип, который принимает выражение (if foo.bar), и тип, который выполняет сопоставление с образцом (if let foo = bar, if case .some(let foo) = bar и т. Д.).

Поскольку Swift поддерживает выражения в скобках, if foo.bar работает так же, как if (foo.bar): в первом случае условие foo.bar, а во втором случае условие (foo.bar). Другими словами, круглые скобки здесь являются частью выражения условия, а не частью оператора if. Это отличается от C ++, где круглые скобки являются частью оператора if. Однако в обоих случаях вы можете добавить столько скобок, сколько хотите: if (((((((((foo.bar))))))))), хотя и глупо, внешне допустимо на обоих языках.

Напомним, что вы можете заключить произвольные выражения в скобки, но вы не можете просто заключить что-либо в скобки. Вы не написали бы (if foo.bar) на Swift или C ++, потому что знаете, что if не является выражением. Затем то же самое относится к let foo = bar. Это также не выражение, поэтому вы не можете заключить его в скобки. if let foo = bar нормально, но if (let foo = bar) нет.

C ++ поддерживает похожий синтаксис в некоторых случаях:

if (auto foo = make_unique<int>(3)) { ... } else { ... }

Этот синтаксис объявляет foo и проверяет его (используя operator bool()), а затем соответствующим образом выполняет ветвление программы. Поскольку условие является оператором объявления, а не выражением, оно также не может быть заключено в дополнительные скобки: if ((auto foo = make_unique<int>(3))) - это ошибка времени компиляции, как и if (let foo = bar) в Swift.

0 голосов
/ 15 января 2019
if (let forSureNames = strArray) {

... это пытается использовать необязательную привязку. Дополнительное связывание позволяет вам безопасно развернуть некоторую необязательную константу / переменную, которая может быть nil. Если это значение присвоено, оно удовлетворяет оператору if с этой развернутой (необязательной) константой / переменной.

Но это не работает с круглыми скобками, так как значения из скобок должны иметь тип Bool. Необязательная привязка не возвращает значение Bool напрямую, она просто пытается присвоить константу / переменную, а неявно возвращает логическое значение в зависимости от того, произошло ли присвоение.

if (true) {...} // works
if (let value = optional) {...} // doesn't work

Итак, вы должны удалить эти скобки

if let forSureNames = strArray {...}

В отличие от других языков, условия в Swift не обязательно должны быть в скобках, и рекомендуется не использовать их, если они не требуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...