Swift 2: Оператор guard

оператор guard

В первую очередь, чтобы попробовать все сделать самому, вам необходимо установить Xcode 7.

Раньше были "пирамиды погибели"

При запуске метода вы хотите быть уверенным, что данные поступающие в него валидны, и метод будет работать корректно. Кодеры решают такие проблемы общепринятым способом - "пирамиды погибели" и ранними возвратами. Например, вот так:

if firstName != "" {
    if lastName != "" {
        if address != "" {
            // do great code
        }
    }
}

А называется этот способ так из-за того, что при выполнении все большего числа вложенных проверок, вырастает и количество отступов, что придает вашему коду форму пирамиды.

Ранние возвращения выглядят вот так:

if firstName == "" { return }
if lastName == "" { return }
if address == "" { return }
// ваш классный код

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

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

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

В Swift ранние возвраты имеют проблему при обработке опционалов. Одной из самых важных проверок в Swift является извлечение опционального значения, но если вы используете if/let в вашем раннем возврате, то ваш опционал покинет область видимости практически моментально, и вы не сможете его использовать. Вам нужно либо переизвлекать его, либо принудительно извлекать его, так как вы точно знаете, что он существует. Вобщем все это мрачно.

Новый оператор guard в Swift 2

В Swift 2 было введено новое ключевое слово guard, которое позволяет улучшить ваши ранние возвраты в трех направлениях:

  1. Делает вашу цель более очевидной: вы говорите guard, что вы хотите видеть, а не то, чего не хотите. guard создан специально для вылавливания невалидных параметров, так что каждый, кто будет читать ваш код, будет явно видеть то, что вы хотите получить.
  2. Все опциональные значения, извлеченные при помощи оператора guard, остаются в пределах видимости даже после того, как guard завершает свою работу, так что вы можете продолжать их использовать. Это означает, что вы проводите проверку и извлечение опционального значения, а затем, просто используете его дальше.
  3. guard позволяет сократить ваш код, что в свою очередь означает меньшее количество багов и более счастливых разработчиков.

Любые условия, которые вы бы проверили при помощи if ранее, теперь вы можете проверить при помощи guard. И вот вам в доказательство несколько примеров:

guard name.characters.count > 0 else {
    throw InputError.NameIsEmpty
}

guard age > 18 else {
    return false
}

guard #available(iOS 9, *) else {
    return
}

func printName() {
    guard let unwrappedName = name else {
        print("You need to provide a name.")
        return
    }

    print(unwrappedName)
}

В последнем примере отображено, как можно извлечь опциональное значение, а затем, использовать его далее. Именно это достоинство guard является его главным преимуществом перед методом ранних возвратов.

Оригинал http://www.hackingwithswift.com/new-syntax-swift-2-guard