protocol swift optional

protocol - ¿Proporcionando un valor predeterminado para un Opcional en Swift?



swift syntax (5)

A partir de agosto de 2014, Swift tiene un operador coalescente (??) que permite eso. Por ejemplo, para un String myOptional opcional, podría escribir:

result = myOptional ?? "n/a"

El modismo para tratar opcionales en Swift parece excesivamente detallado, si todo lo que quiere hacer es proporcionar un valor predeterminado en el caso de que sea nulo:

if let value = optionalValue { // do something with ''value'' } else { // do the same thing with your default value }

que implica duplicar código innecesariamente, o

var unwrappedValue if let value = optionalValue { unwrappedValue = value } else { unwrappedValue = defaultValue }

que requiere que el valor unwrappedValue no sea una constante.

La mónada de Scala''s Option (que es básicamente la misma idea que Swift''s Optional) tiene el método getOrElse para este propósito:

val myValue = optionalValue.getOrElse(defaultValue)

¿Me estoy perdiendo de algo? ¿Swift tiene una forma compacta de hacer eso ya? O, en su defecto, ¿es posible definir getOrElse en una extensión para Opcional?


He creado una biblioteca de extensión simple y la uso para reducir esos códigos repetitivos. Echa y devuelve tipos primitivos opcionales en valor predeterminado. Usted acaba de lanzarlo como a continuación,

CGFloat(optionalValue)

o con cierto valor predeterminado,

Int(optionalValue, defaultValue: 100)

Puedes mirar a través de this repositorio.


Lo siguiente parece funcionar

extension Optional { func getOrElse<T>(defaultValue: T) -> T { if let value = self? { return value as T } else { return defaultValue } } }

sin embargo, la necesidad de arrojar value as T es un hack feo. Idealmente, debería haber una manera de afirmar que T es igual al tipo que figura en el Opcional. Tal como está, escriba los conjuntos de inferencia T función del parámetro dado a getOrElse, y luego falla en el tiempo de ejecución si esto no coincide con el opcional y el opcional es no-nil:

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


si escribiste:

let result = optionalValue ?? 50

y optionalValue != nil , el result también será optional y necesitará desenvolverlo en el futuro

Pero puedes escribir operador

infix operator ??? { associativity left precedence 140 } func ???<T>(optLeft:T?, right:T!) -> T! { if let left = optLeft { return left } else { return right} }

Ahora usted puede:

let result = optionalValue ??? 50

Y cuando optionalValue != nil unwraped result será unwraped


Actualizar

Apple ahora ha agregado un operador coalescente:

var unwrappedValue = optionalValue ?? defaultValue

El operador ternario es tu amigo en este caso

var unwrappedValue = optionalValue ? optionalValue! : defaultValue

También puede proporcionar su propia extensión para la enumeración opcional:

extension Optional { func or(defaultValue: T) -> T { switch(self) { case .None: return defaultValue case .Some(let value): return value } } }

Entonces puedes hacer:

optionalValue.or(defaultValue)

Sin embargo, recomiendo seguir al operador ternario ya que otros desarrolladores lo entenderán mucho más rápido sin tener que investigar el método or método.

Nota : Inicié un module para agregar ayudantes comunes como esta or en Optional para acelerar.