the - Genérico Swift 4 enumeración con tipo asociado vacío
switch enum swift (3)
En Swift 3 puede omitir el valor asociado de tipo Void
:
let res: Result<Void> = .success()
En Swift 4 tienes que pasar un valor asociado de tipo Void
:
let res: Result<Void> = .success(())
// Or just:
let res = Result.success(())
tl; dr
¿Es posible crear una instancia de un miembro de enumeración Swift 4 genérico con un valor asociado de tipo Void
?
Fondo
Estoy usando una enumeración de resultados simple (similar a un resultado antitípico ):
enum Result<T> {
case success(T)
case error(Error?)
}
Ahora me gustaría usar esta enumeración para representar el resultado de una operación que no produce un valor de resultado real; La operación se ha realizado correctamente o ha fallado . Para esto definiría el tipo como Result<Void>
, pero estoy luchando con la forma de crear la instancia del Resultado, ni let res: Result<Void> = .success
ni let res: Result<Void> = .success()
trabaja.
En Swift 4, un caso de enumeración con un valor asociado de Void
ya no es equivalente a un caso de enumeración con una lista vacía de valores asociados.
Creo que esto es, como dice Martin , un resultado de SE-0029 en el que ya no se puede pasar una tupla de argumentos a una función y hacer que se "repartan" en todos los parámetros (aunque la propuesta se marcó implementada en Swift 3, creo este caso particular fue recogido más tarde en la implementación de SE-0110 para Swift 4).
Como resultado, esto significa que ya no puede llamar a (Void) -> T
como a () -> T
en Swift 4. Ahora tiene que pasar Void
explícitamente:
let result = Result.success(())
Sin embargo, me parece bastante feo, por lo general implemento una extensión como esta:
extension Result where T == Void {
static var success: Result {
return .success(())
}
}
Lo que te permite decir cosas como esta:
var result = Result.success
result = .success
Vale la pena señalar que esta solución no solo se limita a los casos de enumeración, sino que también se puede utilizar con los métodos en general. Por ejemplo:
struct Foo<T> {
func bar(_ a: T) {}
}
extension Foo where T == Void {
func bar() { bar(()) }
}
let f = Foo<Void>()
// without extension:
f.bar(())
// with extension:
f.bar()
Void es una tipografía simple para tupla vacía: (), así que puedes usarla como cualquiera de las siguientes:
let res1: Result<Void> = .success(())
let res2 = Result<Void>.success(())
let res3 = Result.success(() as Void)
let res4 = Result.success(())