diff --git a/src/ch09-01-unrecoverable-errors-with-panic.md b/src/ch09-01-unrecoverable-errors-with-panic.md index 0b7d2db8..a234e8f8 100644 --- a/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/src/ch09-01-unrecoverable-errors-with-panic.md @@ -6,13 +6,13 @@ causar un panic en la práctica: tomando una acción que hace que nuestro códig entre en pánico (como acceder a una matriz más allá del final) o llamando explícitamente a la macro `panic!`. En ambos casos, causamos un pánico en nuestro programa. De forma predeterminada, estos pánicos imprimirán un mensaje -de error, desenrollarán, limpiarán la pila y se cerrarán. A través de una +de error, se desharán, limpiarán la pila y se cerrarán. A través de una variable de entorno, también puede hacer que Rust muestre la pila de llamadas cuando ocurre un pánico para facilitar el seguimiento de la fuente del panic. -> ### Desenrollar el Stack o Abortar en respuesta a un Panic +> ### Deshacer la pila o abortar en respuesta a un pánico > -> Por defecto, cuando ocurre un panic, el programa comienza a _desenrollar_, +> Por defecto, cuando ocurre un panic, el programa comienza a _deshacerse_, > lo que significa que Rust retrocede por la pila y limpia los datos de cada > función que encuentra. Sin embargo, este retroceso y limpieza es mucho > trabajo. Rust, por lo tanto, le permite elegir la alternativa de _abortar_ @@ -20,7 +20,7 @@ cuando ocurre un pánico para facilitar el seguimiento de la fuente del panic. > > La memoria que el programa estaba usando deberá ser limpiada > por el sistema operativo. Si en su proyecto necesita hacer que el binario -> resultante sea lo más pequeño posible, puede cambiar de desenrollar a abortar +> resultante sea lo más pequeño posible, puede cambiar de deshacer el programa a abortarlo > al producir un pánico agregando `panic = 'abort'` a las secciones > `[profile]` apropiadas en su archivo _Cargo.toml_. Por ejemplo, si desea > abortar en caso de pánico en el modo de lanzamiento, agregue esto: @@ -54,16 +54,16 @@ línea, vemos la llamada a la macro `panic!`. En otros casos, la llamada a `panic!` podría estar en el código que nuestro código llama, y el nombre de archivo y el número de línea informados por el mensaje de error serán el código de otra persona donde se llama a la macro `panic!`, no la línea de -nuestro código que finalmente condujo a la llamada a `panic!`. Podemos usar la -traza de las funciones de las que provino la llamada a `panic!` para +nuestro código que finalmente condujo a la llamada a `panic!`. Podemos usar el +backtrace de las funciones de las que provino la llamada a `panic!` para determinar la parte de nuestro código que está causando el problema. -Discutiremos las trazas en más detalle a continuación. +Discutiremos el backtrace en más detalle a continuación. -### Usando un Backtrace de `panic!` +### Usando el backtrace de `panic!` Veamos otro ejemplo de cómo es cuando una llamada a `panic!` proviene de una biblioteca debido a un error en nuestro código en lugar de que nuestro código -llame directamente a la macro. La lista 9-1 tiene algún código que intenta +llame directamente a la macro. El listado 9-1 tiene algún código que intenta acceder a un índice en un vector más allá del rango de índices válidos. Filename: src/main.rs @@ -72,7 +72,7 @@ acceder a un índice en un vector más allá del rango de índices válidos. {{#rustdoc_include ../listings/ch09-error-handling/listing-09-01/src/main.rs}} ``` -Listing 9-1: Intentando acceder a un elemento más allá del +Listado 9-1: Intentando acceder a un elemento más allá del fin de un vector, que provocará una llamada a `panic!` Aquí, estamos intentando acceder al elemento 100 de nuestro vector (que está @@ -99,17 +99,17 @@ continuar. Intentémoslo y veamos: Este error apunta a la línea 4 de nuestro `main.rs` donde intentamos acceder al índice 99. La siguiente línea de nota nos dice que podemos establecer la -variable de entorno `RUST_BACKTRACE` para obtener una traza de exactamente lo -que sucedió para causar el error. Una _traza_ es una lista de todas las -funciones que se han llamado para llegar a este punto. Las trazas en Rust -funcionan como lo hacen en otros lenguajes: la clave para leer la traza es +variable de entorno `RUST_BACKTRACE` para obtener el backtrace de exactamente lo +que sucedió para causar el error. El _Backtrace_ es una lista de todas las +funciones que se han llamado para llegar a este punto. El backtrace en Rust +funciona como lo hacen en otros lenguajes: la clave para leer el backtrace es comenzar desde la parte superior y leer hasta que vea archivos que escribió. Ese es el lugar donde se originó el problema. Las líneas por encima de ese punto son el código que su código ha llamado; las líneas a continuación son el código que llamó a su código. Estas líneas antes y después pueden incluir -código de Rust core, código de biblioteca estándar o cajas que está usando. -Intentemos obtener una traza estableciendo la variable de entorno -`RUST_BACKTRACE` a cualquier valor excepto 0. La lista 9-2 muestra una salida +código de Rust core, código de biblioteca estándar o crates que estés usando. +Intentemos obtener el backtrace estableciendo la variable de entorno +`RUST_BACKTRACE` a cualquier valor excepto 0. El listado 9-2 muestra una salida similar a la que verás. {{#rustdoc_include ../listings/ch09-error-handling/listing-09-05/src/main.rs}} ``` -Listing 9-5: Manejando diferentes tipos de errores de +Listado 9-5: Manejando diferentes tipos de errores de diferentes formas El tipo de valor que `File::open` devuelve dentro de la variante `Err` es @@ -143,7 +143,7 @@ archivo faltante. > más concisos que usar `match` al manejar valores `Result` en tu código. > > Por ejemplo, aquí hay otra forma de escribir la misma lógica que se muestra en -> el Listado 9-5, esta vez usando closures y el método `unwrap_or_else`: +> el listado 9-5, esta vez usando closures y el método `unwrap_or_else`: > > > @@ -164,7 +164,7 @@ archivo faltante. > } > ``` > -> Aunque este código tiene el mismo comportamiento que el Listado 9-5, no +> Aunque este código tiene el mismo comportamiento que el listado 9-5, no > contiene ninguna expresión `match` y es más fácil de leer. Vuelve a este > ejemplo después de leer el Capítulo 13, y busca el método `unwrap_or_else` en > la documentación de la biblioteca estándar. Muchos más de estos métodos pueden @@ -176,7 +176,7 @@ Usando `match` funciona bastante bien, pero puede ser un poco verboso y no siempre comunica bien la intención. El tipo `Result` tiene muchos métodos auxiliares definidos en él para hacer varias tareas más específicas. El método `unwrap` es un método de atajo implementado exactamente como la expresión -`match` que escribimos en el Listado 9-4. Si el valor `Result` es la variante +`match` que escribimos en el listado 9-4. Si el valor `Result` es la variante `Ok`, `unwrap` devolverá el valor dentro de `Ok`. Si el `Result` es la variante `Err`, `unwrap` llamará a la macro `panic!` por nosotros. Aquí hay un ejemplo de `unwrap` en acción: @@ -245,7 +245,7 @@ control al código que llama, donde puede haber más información o lógica que dicte cómo se debe manejar el error que la que tienes disponible en el contexto de tu código. -Por ejemplo, El Listado 9-6 muestra una función que lee un nombre de usuario de +Por ejemplo, El listado 9-6 muestra una función que lee un nombre de usuario de un archivo. Si el archivo no existe o no se puede leer, esta función devolverá esos errores al código que llamó a la función. @@ -259,7 +259,7 @@ don't want to include it for rustdoc testing purposes. --> {{#include ../listings/ch09-error-handling/listing-09-06/src/main.rs:here}} ``` -Listing 9-6: Una función que devuelve errores al código +Listado 9-6: Una función que devuelve errores al código llamado usando `match` Esta función se puede escribir de una manera mucho más corta, pero vamos a @@ -318,7 +318,7 @@ el operador de interrogación `?` para hacer esto más fácil. #### Un atajo para propagar errores: el operador `?` -El Listado 9-7 muestra una implementación de `read_username_from_file` que tiene +El listado 9-7 muestra una implementación de `read_username_from_file` que tiene la misma funcionalidad que en el Listado 9-6, pero esta implementación utiliza el operador `?`. @@ -332,18 +332,18 @@ don't want to include it for rustdoc testing purposes. --> {{#include ../listings/ch09-error-handling/listing-09-07/src/main.rs:here}} ``` -Listing 9-7: Una función que devuelve errores al código +Listado 9-7: Una función que devuelve errores al código llamado usando el operador `?` El `?` colocado después de un valor `Result` se define para funcionar de casi la misma manera que las expresiones `match` que definimos para manejar los -valores `Result` en el Listado 9-6. Si el valor de `Result` es un `Ok`, el +valores `Result` en el listado 9-6. Si el valor de `Result` es un `Ok`, el valor dentro del `Ok` se devolverá de esta expresión, y el programa continuará. Si el valor es un `Err`, él `Err` se devolverá de toda la función como si hubiéramos usado la palabra clave `return` para que el valor de error se propague al código que llama. -Hay una diferencia entre lo que hace la expresión `match` del Listado 9-6 y lo +Hay una diferencia entre lo que hace la expresión `match` del listado 9-6 y lo que hace el operador `?`: los valores de error que tienen el operador `?` llamado en ellos pasan a través de la función `from`, definida en el trait `From` en la biblioteca estándar, que se usa para convertir valores de un tipo @@ -354,14 +354,14 @@ representar todas las formas en que una función podría fallar, incluso si las partes podrían fallar por muchas razones diferentes. Por ejemplo, podríamos cambiar la función `read_username_from_file` en el -Listado 9-7 para devolver un tipo de error personalizado llamado `OurError` que +listado 9-7 para devolver un tipo de error personalizado llamado `OurError` que definimos. Si también definimos `impl From for OurError` para construir una instancia de `OurError` a partir de un `io::Error`, entonces el operador `?` llama en el cuerpo de `read_username_from_file` llamará a `from` y convertirá los tipos de error sin necesidad de agregar más código a la función. -En el contexto del Listado 9-7, el `?` al final de la llamada a `File::open` +En el contexto del listado 9-7, el `?` al final de la llamada a `File::open` devolverá el valor dentro de un `Ok` a la variable `username_file`. Si ocurre un error, el `?` operador devolverá temprano toda la función y dará cualquier valor `Err` al código que llama. Lo mismo se aplica al `?` al final de la @@ -382,7 +382,7 @@ don't want to include it for rustdoc testing purposes. --> {{#include ../listings/ch09-error-handling/listing-09-08/src/main.rs:here}} ``` -Listing 9-8: Método de encadenamiento +Listado 9-8: Método de encadenamiento llamado después del operador `?` Hemos movido la creación del nuevo `String` en `username` al principio de la @@ -392,10 +392,10 @@ sobre el resultado de `File::open("hello.txt")?`. Todavía tenemos un `?` al final de la llamada a `read_to_string`, y todavía devolvemos un valor `Ok` que contiene `username` cuando tanto `File::open` como `read_to_string` tienen éxito en lugar de devolver errores. La funcionalidad es nuevamente la -misma que en el Listado 9-6 y el Listado 9-7; esta es solo una forma diferente +misma que en el listado 9-6 y el listado 9-7; esta es solo una forma diferente y más ergonómica de escribirla. -El Listado 9-9 muestra una forma de hacer esto aún más conciso usando +El listado 9-9 muestra una forma de hacer esto aún más conciso usando `fs::read_to_string`. Filename: src/main.rs @@ -408,7 +408,7 @@ don't want to include it for rustdoc testing purposes. --> {{#include ../listings/ch09-error-handling/listing-09-09/src/main.rs:here}} ``` -Listing 9-9: Usando `fs::read_to_string` en lugar de +Listado 9-9: Usando `fs::read_to_string` en lugar de abrir y luego leer el archivo Leer un archivo en un `String` es una operación bastante común, por lo que la @@ -423,12 +423,12 @@ errores, por lo que lo hicimos de la manera más larga primero. El operador `?` solo puede usarse en funciones cuyo tipo de retorno sea compatible con el valor que se usa con el operador `?`. Porque el operador `?` está definido para realizar una devolución temprana de un valor de la función, -de la misma manera que la expresión `match` que definimos en el Listado 9-6. -En el Listado 9-6, el `match` estaba usando un valor `Result`, y el brazo de +de la misma manera que la expresión `match` que definimos en el listado 9-6. +En el listado 9-6, el `match` estaba usando un valor `Result`, y el brazo de devolución temprana devolvió un valor `Err(e)`. El tipo de retorno de la función debe ser un `Result` para que sea compatible con este `return`. -En el Listado 9-10, veamos el error que obtendremos si usamos el operador `?` +En el listado 9-10, veamos el error que obtendremos si usamos el operador `?` en una función `main` con un tipo de retorno incompatible con el tipo de valor que usamos `?`: @@ -438,7 +438,7 @@ que usamos `?`: {{#rustdoc_include ../listings/ch09-error-handling/listing-09-10/src/main.rs}} ``` -Listing 9-10: Intentando usar el `?` en la función `main` +Listado 9-10: Intentando usar el `?` en la función `main` que devuelve `()` no se compilará Este código abre un archivo, que puede fallar. El operador `?` sigue el valor @@ -467,14 +467,14 @@ comportamiento del operador `?` cuando se llama en un `Option` es similar a su comportamiento cuando se llama en un `Result`: si el valor es `None`, el `None` se devolverá temprano desde la función en ese punto. Si el valor es `Some`, el valor dentro de `Some` es el valor resultante de la expresión y la -función continúa. El Listado 9-11 tiene un ejemplo de una función que encuentra +función continúa. El listado 9-11 tiene un ejemplo de una función que encuentra el último carácter de la primera línea en el texto dado: ```rust {{#rustdoc_include ../listings/ch09-error-handling/listing-09-11/src/main.rs:here}} ``` -Listing 9-11: Using the `?` operator on an `Option` +Listado 9-11: Using the `?` operator on an `Option` value Esta función devuelve `Option` porque es posible que haya un carácter @@ -512,7 +512,7 @@ programas ejecutables, y hay restricciones sobre cuál puede ser su tipo de retorno para que los programas se comporten como se espera. Por suerte, `main` también puede devolver un `Result<(), E>`. El Listado 9-12 -tiene el código del Listado 9-10, pero hemos cambiado el tipo de retorno de +tiene el código del listado 9-10, pero hemos cambiado el tipo de retorno de `main` para que sea `Result<(), Box>` y hemos agregado un valor de retorno `Ok(())` al final. Este código ahora se compilará: @@ -520,7 +520,7 @@ retorno `Ok(())` al final. Este código ahora se compilará: {{#rustdoc_include ../listings/ch09-error-handling/listing-09-12/src/main.rs}} ``` -Listing 9-12: Cambiando `main` devuelve `Result<(), E>` +Listado∂ 9-12: Cambiando `main` devuelve `Result<(), E>` permitiendo el uso del operador `?` en valores `Result` El `Box` tipo es un _trait object_, que hablaremos en la sección