Идиома для работы с опциями в Swift кажется чрезмерно многословной, если все, что вы хотите сделать, это указать значение по умолчанию в случае, если оно равно нулю:
if let value = optionalValue {
// do something with 'value'
} else {
// do the same thing with your default value
}
что включает в себя ненужное дублирование кода, или
var unwrappedValue
if let value = optionalValue {
unwrappedValue = value
} else {
unwrappedValue = defaultValue
}
который unwrappedValue
не требует постоянного значения.
Монада Option в Scala (которая по сути совпадает с идеей необязательной в Swift) имеет getOrElse
для этой цели метод :
val myValue = optionalValue.getOrElse(defaultValue)
Я что-то упускаю? У Swift уже есть компактный способ сделать это? Или, в противном случае, можно ли определить getOrElse
расширение для Optional?
Ответы:
Обновить
Apple добавила оператор объединения:
var unwrappedValue = optionalValue ?? defaultValue
Тернарный оператор в этом случае ваш друг
var unwrappedValue = optionalValue ? optionalValue! : defaultValue
Вы также можете предоставить собственное расширение для необязательного перечисления:
extension Optional { func or(defaultValue: T) -> T { switch(self) { case .None: return defaultValue case .Some(let value): return value } } }
Тогда вы можете просто сделать:
Тем не менее, я рекомендую придерживаться тернарного оператора, так как другие разработчики поймут это гораздо быстрее, не исследуя
or
метод.Примечание : Я начал модуль для добавления общих помощников , как это
or
наOptional
Свифт.источник
unwrappedValue
прежнему является необязательным типом для этого случая в Swift 1.2:var unwrappedValue = optionalValue ? optionalValue! : defaultValue
(xcode 6 beta 4). Это изменилось???
виду: поведение вывода типа по умолчанию заключается в том, что он возвращает необязательный параметр, что обычно не является тем, что вам нужно. Вы можете объявить переменную как необязательную, и это прекрасно работает.По состоянию на август 2014 года в Swift есть оператор объединения (??), который позволяет это. Например, для необязательного String myOptional вы можете написать:
result = myOptional ?? "n/a"
источник
если вы написали:
let result = optionalValue ?? 50
и
optionalValue != nil
тогдаresult
будетoptional
тоже, и вам нужно будет развернуть его в будущемНо вы можете написать оператор
infix operator ??? { associativity left precedence 140 } func ???<T>(optLeft:T?, right:T!) -> T! { if let left = optLeft { return left } else { return right} }
Теперь вы можете:
let result = optionalValue ??? 50
И когда
optionalValue != nil
тогдаresult
будетunwraped
источник
Кажется, работает следующее
extension Optional { func getOrElse<T>(defaultValue: T) -> T { if let value = self? { return value as T } else { return defaultValue } } }
однако необходимость в приведении
value as T
- уродливый прием. В идеале должен быть способ утверждения, которыйT
совпадает с типом, содержащимся в Optional. В существующем виде введите наборы для выводаT
основаны на параметре, заданном для getOrElse, а затем завершаются ошибкой во время выполнения, если это не соответствует необязательному, а параметр Optional не равен нулю:let x: Int? let y = x.getOrElse(1.414) // y inferred as Double, assigned 1.414 let a: Int? = 5 let b: Double = a.getOrElse(3.14) // Runtime failure casting 5 to Double
источник
T
метод не нужно . Это фактически отменяет существующееT
из Optional. Вы можете просто сделать:func getOrElse(defaultValue: T) -> T
тогда T относится к типу реального значения необязательного, и вам не нужно вводить его, проверьте егоT
в этом? (помимо простого предположения, основанного на соглашении)Optional
внутри Xcode,enum Optional<T>