swift - novio - ellie goulding premios




¿Qué es el tipo Never return? (3)

Para comprender mejor Never and Void , y cómo Never es útil en más contextos que el antiguo @noreturn , primero veamos cómo se definen realmente los dos tipos como:

Never se define here como:

public enum Never {}

Como no hay manera de crear una instancia de un valor de una enumeración vacía, el sistema de tipos garantiza que no puede existir ninguna instancia de Never . Esto significa que las funciones que especifican su tipo de devolución como Never se evitan por el sistema de tipos en cualquier circunstancia.

El compilador tiene esto en cuenta cuando hace un análisis de flujo de control. Por ejemplo, estas dos funciones se compilan sin error, mientras que fallarían si una función que devuelve Void se sustituya por fatalError :

func foo(fail: Bool) -> String {
    if fail {
        fatalError()
    } else {
        return "foo"
    }
    // notice there is no return statement here
}

func bar(fail: Bool) -> Void {
    let s: String
    if fail {
        fatalError()
        // the compiler doesn't complain s is not initialized here
    } else {
        s = "bar"
    }
    print(s)
}

Void se define here como:

public typealias Void = ()

No hay dos instancias diferentes de una tupla vacía. Por lo tanto, el valor de retorno de las funciones que devuelven Void no contiene información.

Realmente puedes escribir return () o return Void() . También puedes usar el "valor" devuelto, así:

func empty() -> Void {}
let v = empty()
print(type(of: v)) // prints "()"

aunque el compilador advertirá que "Constante 'v' tiene el tipo 'Vacío', lo que puede ser inesperado".

Definir ambos, Never y Void en términos del sistema de tipos en lugar de como características especiales del lenguaje, nos permite hacer cosas muy inteligentes con los genéricos. Veamos un ejemplo de un tipo de Result , genérico sobre el tipo de éxito y fracaso.

enum Result<R, E> {
    case success(R)
    case failure(E)
}

Una posible especialización de esto sería Result<Void, MyError> . Esto significaría que tiene un resultado que, en caso de éxito, no contiene ninguna información más allá del hecho de que tuvo éxito.

Otra posibilidad podría ser Result<String, Never> . El compilador garantiza que este resultado nunca será el caso de falla.

Los opcionales interactúan con Never y el Void de manera similar. Never? ¿Solo puede ser nulo, y Void? solo guarda la información si es nula o no, nada más (es básicamente un Bool más complicado). Ambos de estos no son muy útiles por sí solos, pero pueden aparecer cuando Never o Void se utilizan como parámetros genéricos en algún lugar.

En la práctica, raramente escribirá funciones que vuelven Never . Personalmente lo he usado para envolver fatalError para crear una función que uso para marcar funciones que aún no están implementadas:

func unimplemented(f: String = #function) -> Never {
    fatalError("\(f) is not implemented yet")
}

Otro ejemplo de una función que devuelve Never es dispatchMain() , que se puede usar en las utilidades de línea de comandos para iniciar DispatchQueue.main . Como esta cola espera nuevos bloques, dispatchMain() nunca regresa.

¿Qué hace una func con tipo de retorno Never hacer?

Por ejemplo:

func addNums() -> Never {

    //my code

}

¿Cuál será la diferencia si mantengo el tipo de devolución como Void esta manera?

func addNums() -> Void {

    //my code

}

Supongamos que deseo manejar un fatalError (como dice dpassage ); El siguiente código será suficiente:

print("its an error")
return

La documentación de Apple dice:

El tipo de retorno de funciones que no devuelven normalmente, es decir, un tipo sin valores.

Fuente: Developer

Esta no fue una pregunta duplicada de ¿ Cuándo y cómo usar el atributo @noreturn en Swift? , como deseo una respuesta más detallada que necesita detalles como:

  1. Ejemplos prácticos sobre la diferencia entre los tipos Never y Void como retorno.

  2. Condición por la cual debemos adoptar estos tipos de devolución.

  3. También existe la posibilidad de que el tipo de retorno sea nulo; Necesito una comparación de esa característica también

La respuesta debe centrarse en las diferencias.


Never indica que la función nunca volverá. Está diseñado para ser utilizado para cosas como fatalError que causan que su programa se bloquee intencionalmente, a menudo después de registrar un error. Probablemente no debería usarlo a menos que esté haciendo algo como hacer un controlador para errores catastróficos en su aplicación.

Esto es diferente de una función que simplemente no devuelve un valor, como en su segundo fragmento. También puede escribir eso como func addNums() -> Void .


Vacío

Void es en sí mismo un tipo de retorno que es una tupla con cero elementos. Puedes usar Void y () indistintamente.

Mira estos ejemplos,

  1. func yourFunc() {} Esta es una función sin tipo de retorno, que básicamente devuelve una tupla con cero elementos, que se puede escribir como ()

  2. func yourFunc() -> Void {} Función que informa explícitamente al compilador sobre el tipo de devolución de void

  3. func yourFunc() -> () {} Este tipo de retorno de () muestra lo mismo que el tipo void. () indica una tupla con cero elementos

Nunca

Nunca devolver-tipo informa al compilador que no existe la necesidad de devolver una tupla (). Además, la función con el tipo de nunca retorno se usa para el punto de salida de la ejecución actual, como un bloqueo, un error fatal, un aborto o una salida.

Para una comprensión detallada de nunca , echemos un vistazo a un ejemplo abort ():

1.

 func yourFunc() {
    abort()
    print("Will not reach at this point") //Warning for this line
} 

2.

 func yourFunc() -> Int {
    if true {
        abort()
    } else {
        return 1
    }
}

De los fragmentos de código anteriores, podemos ver cuando llamamos abort () (que no devuelve un valor) como la última instrucción en una función que espera que se devuelva un valor (en nuestro caso Int). El compilador no genera una advertencia.

abortar()

public func abort() -> Never

Similarmente para exit ():

public func exit(_: Int32) -> Never

La documentación de Apple dice: " Use Nunca como el tipo de retorno al declarar un cierre, función o método que incondicionalmente arroja un error, atrapa o no termina " .

Entonces, si desea escribir una función personalizada que registre un error catastrófico , debe usar el tipo de retorno Nunca para señalar al compilador:

func catastrophicErrorDisplay(error: String) -> Never {
    DisplaySomeCustomLogFacility(error)
}

En resumen " Nunca se usa para fallas repentinas y totales de las cuales la recuperación es imposible " .







types