Эта идиома Свифта имеет смысл
if let x = someDict[someKey] { ... }
Однако я действительно хочу
if let x = someDict[someKey], y = someDict[someOtherKey] { ... }
Как написано, это неверно, но возможно ли это?
Эта идиома Свифта имеет смысл
if let x = someDict[someKey] { ... }
Однако я действительно хочу
if let x = someDict[someKey], y = someDict[someOtherKey] { ... }
Как написано, это неверно, но возможно ли это?
Обновление для Swift 1.2
Так как Swift 1.2, if let
позволяет разворачивать несколько опций, поэтому теперь вы можете просто написать это, как в вашем примере:
if let x = someDict[someKey], y = someDict[someOtherKey] { … }
Вы можете даже чередовать условия, такие как:
if let x = someDict[someKey] where x == "value", y = someDict[someOtherKey] { … }
Это было раньше, чем Swift 1.2
Вот как вы могли бы сделать это без уродливой силы-upwrapping:
switch (dict["a"], dict["b"]) {
case let (.Some(a), .Some(b)):
println("match")
default:
println("no match")
}
На самом деле все еще довольно многословно.
Это работает, потому что необязательный тип формы Type?
фактически сокращен для Optional<Type>
, который представляет собой перечисление, которое выглядит примерно так:
enum Optional<T> {
case None
case Some(T)
}
Затем вы можете использовать сопоставление шаблонов, как и для любого другого перечисления.
Изменить: Я видел, как люди пишут вспомогательные функции, подобные этой (извините за отсутствие атрибуции, я не помню, где я ее видел):
func unwrap<A, B>(a: A?, b: B?) -> (A, B)? {
switch (a, b) {
case let (.Some(a), .Some(b)):
return (a, b)
default:
return nil
}
}
Затем вы можете продолжать использовать конструкцию if let
, а именно:
if let (a, b) = unwrap(dict["a"], dict["b"]) {
println("match: \(a), \(b)")
} else {
println("no match")
}
В Swift 1.2 (часть Xcode 6.3), if let
необязательная конструкция привязки может связывать несколько опций, используя тот же синтаксис, который найден в этом вопросе.
if let x = someDict[someKey], y = someDict[someOtherKey] { ... }
Вы также можете расширить это с помощью условий для связанных значений:
if let a = foo(), b = bar(), a < b, let c = baz() { ... }
Шаблон switch
для обработки множественного необязательного связывания (см. этот ответ) остается в силе. Хотя с условиями if let
guard вы можете найти меньше вариантов использования для него, оно все еще существует, если вы хотите, например, обрабатывать случаи множественного необязательного связывания с различным поведением, когда разные подмножества тестируемых опций являются нулевыми.
(Примечание: до Swift 3, if let a = ..., b = ..., a < b
используется where
, чтобы разделить привязку с условным.)
В Swift1.2 вы можете использовать несколько необязательных привязок.
if let x = someDict[someKey], y = someDict[someOtherKey] { ... }
Обратите внимание, что y неявно объявляется как константа, что совпадает с x. Вышеприведенный код эквивалентен следующему.
if let x = someDict[someKey],let y = someDict[someOtherKey] { ... }
Если вы хотите явно объявить y как изменяемый тип, просто введите var перед именем переменной.
if let x = someDict[someKey],var y = someDict[someOtherKey] { ... }