Skip to content

Commit

Permalink
Merge branch 'main' into only-new-async
Browse files Browse the repository at this point in the history
  • Loading branch information
Phosphorus-M authored Dec 8, 2024
2 parents de5487b + e66e486 commit 66406b7
Show file tree
Hide file tree
Showing 14 changed files with 464 additions and 43 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pr-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ on:
pull_request_target:
types:
- opened
- synchronize
- closed

# cancel in-progress runs on new commits to same PR (github.event.number)
Expand Down
30 changes: 30 additions & 0 deletions ferris.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ body.rust .panics,
body.rust .not_desired_behavior {
background: #fff1f1;
}
html.rust, html.light{
--sidebar-image: url(../img/RustLangES-light.svg);
}
html.navy, html.ayu, html.coal{
--sidebar-image: url(../img/RustLangES-dark.svg);
}
body{
container-name: body;
}

body.coal .does_not_compile,
body.coal .panics,
Expand Down Expand Up @@ -43,3 +52,24 @@ body.ayu .not_desired_behavior {
.ferris-explain {
width: 100px;
}
.sidebar-image {
width: var(--sidebar-width);
height: 100px;
background-image: var(--sidebar-image);
background-repeat: no-repeat;
background-size: contain;
position: absolute;
background-position: center;
top: 0;
}
.sidebar .sidebar-scrollbox{
margin-top: 100px;
}

.logo-separator{
height: 100px;
width: var(--sidebar-width);
position: fixed;
z-index: 1;
background: var(--quote-bg);
}
6 changes: 3 additions & 3 deletions src/appendix-02-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ sobrecargar ese operador.
| `:` | `ident: expr` | Inicializador de campo de estructura | |
| `:` | `'a: loop {...}` | Etiqueta de bucle | |
| `;` | `expr;` | Terminador de declaración y elemento | |
| `;` | `[...; len]` | Parte de la sintaxis de matriz de tamaño fijo | |
| `;` | `[...; len]` | Parte de la sintaxis de arreglos de tamaño fijo | |
| `<<` | `expr << expr` | Desplazamiento a la izquierda | `Shl` |
| `<<=` | `var <<= expr` | Desplazamiento a la izquierda y asignación | `ShlAssign` |
| `<` | `expr < expr` | Comparador de menor que | `PartialOrd` |
Expand Down Expand Up @@ -199,8 +199,8 @@ Tabla B-10 muestra los contextos en los que se usan los corchetes.

| Contexto | Explicación |
|---------|-------------|
| `[...]` | Expresión de matriz |
| `[type; expr]` | Matriz de tipo y tamaño |
| `[...]` | Expresión de arreglo |
| `[type; expr]` | Arreglo de tipo y tamaño |
| `expr[expr]` | Índice de colección. Sobrecargable (`Index`, `IndexMut`) |
| `expr[..]`, `expr[a..]`, `expr[..b]`, `expr[a..b]` | Índice de colección fingiendo ser recortes de colección, usando `Range`, `RangeFrom`, `RangeTo`, o `RangeFull` como el “índice” |

2 changes: 1 addition & 1 deletion src/ch02-00-guessing-game-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ manejador de la entrada estándar para tu terminal.
A continuación, la línea `.read_line(&mut guess)` llama al método
[`read_line`][read_line]<!-- ignore --> en el manejador de entrada estándar para
obtener la entrada del usuario. También estamos pasando `&mut guess` como
argumento a `read_line` para decirle qué cadena almacenar la entrada del
argumento a `read_line` para decirle en qué cadena almacenar la entrada del
usuario. El trabajo completo de `read_line` es tomar lo que el usuario escribe
en la entrada estándar y agregar eso a una cadena (sin sobrescribir su
contenido), por lo que, por lo tanto, pasamos esa cadena como argumento. La
Expand Down
46 changes: 36 additions & 10 deletions src/ch03-02-data-types.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
## Tipos de datos

Cada valor en Rust es de un cierto *tipo de dato*, que le dice a Rust qué tipo
de dato se está especificando para que sepa cómo trabajar con ese dato. Veremos dos subconjuntos de tipos de datos: escalares y compuestos.
de dato se está especificando para que sepa cómo trabajar con ese dato. Veremos
dos subconjuntos de tipos de datos: escalares y compuestos.

Tenga en cuenta que Rust es un lenguaje *estáticamente tipado*, lo que significa
que debe conocer los tipos de todas las variables en tiempo de compilación. El
Expand Down Expand Up @@ -201,7 +202,9 @@ El tipo `char` de Rust es el tipo alfabético más primitivo del lenguaje. Estos
```

Tenga en cuenta que especificamos literales `char` con comillas simples, en
oposición a literales de cadena, que usan comillas dobles. El tipo `char` de Rust tiene un tamaño de cuatro bytes y representa un valor escalar Unicode, lo que significa que puede representar mucho más que ASCII. Letras
oposición a literales de cadena, que usan comillas dobles. El tipo `char` de
Rust tiene un tamaño de cuatro bytes y representa un valor escalar Unicode, lo
que significa que puede representar mucho más que ASCII. Letras
acentuadas; Caracteres chinos, japoneses y coreanos; Emojis; y espacios de ancho
cero son todos valores `char` válidos en Rust. Los valores escalar de Unicode
van desde `U+0000` a `U+D7FF` y `U+E000` a `U+10FFFF` inclusive. Sin embargo,
Expand All @@ -213,22 +216,29 @@ UTF-8 con cadenas”][strings]<!-- ignore --> en el capítulo 8.
### Tipos compuestos

*Tipos compuestos* pueden agrupar múltiples valores en un solo tipo. Rust
tiene dos tipos compuestos primitivos: tuplas y matrices.
tiene dos tipos compuestos primitivos: tuplas y arreglos.

#### El Tipo Tupla

Una *tupla* es una forma general de agrupar varios valores de distintos tipos en un tipo compuesto. Las tuplas tienen una longitud fija: una vez declaradas, su tamaño no puede aumentar ni disminuir.
Una *tupla* es una forma general de agrupar varios valores de distintos tipos en
un tipo compuesto. Las tuplas tienen una longitud fija: una vez declaradas, su
tamaño no puede aumentar ni disminuir.

Creamos una tupla escribiendo una lista de valores separados por comas dentro de
paréntesis. Cada posición de la tupla tiene un tipo, y los tipos de los distintos valores de la tupla no tienen por qué ser iguales. En este ejemplo hemos añadido anotaciones de tipo opcionales:
paréntesis. Cada posición de la tupla tiene un tipo, y los tipos de los
distintos valores de la tupla no tienen por qué ser iguales. En este ejemplo
hemos añadido anotaciones de tipo opcionales:

<span class="filename">Nombre de archivo: src/main.rs</span>

```rust
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs}}
```

La variable `tup` se vincula a toda la tupla porque una tupla se considera un único elemento compuesto. Para obtener los valores individuales de una tupla, podemos utilizar la concordancia de patrones para desestructurar un valor de tupla, así:
La variable `tup` se vincula a toda la tupla porque una tupla se considera un
único elemento compuesto. Para obtener los valores individuales de una tupla,
podemos utilizar la concordancia de patrones para desestructurar un valor de
tupla, así:

<span class="filename">Nombre de archivo: src/main.rs</span>

Expand Down Expand Up @@ -321,7 +331,9 @@ de una manera más concisa.

##### Accediendo a los Elementos del Arreglo

Un arreglo es un trozo de memoria de tamaño fijo y conocido que puede asignarse a la pila. Se puede acceder a los elementos de una matriz utilizando la indexación, de la siguiente manera:
Un arreglo es un trozo de memoria de tamaño fijo y conocido que puede asignarse
a la pila. Se puede acceder a los elementos de una arreglo utilizando la
indexación, de la siguiente manera:

<span class="filename">Nombre de archivo: src/main.rs</span>

Expand Down Expand Up @@ -362,9 +374,23 @@ index out of bounds: the len is 5 but the index is 10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

El programa dio lugar a un *error en tiempo de ejecución* al momento de utilizar un valor no válido en la operación de indexación. El programa salió con un mensaje de error y no ejecutó la sentencia final `println!`. Cuando intentas acceder a un elemento utilizando la indexación, Rust comprobará que el índice que has especificado es menor que la longitud del array. Si el índice es mayor o igual que la longitud, Rust entrará en pánico. Esta comprobación tiene que ocurrir en tiempo de ejecución, especialmente en este caso, porque el compilador no puede saber qué valor introducirá el usuario cuando ejecute el código más tarde.

Este es un ejemplo de los principios de seguridad de memoria de Rust en acción. En muchos lenguajes de bajo nivel, este tipo de comprobación no se hace, y cuando proporcionas un índice incorrecto, se puede acceder a memoria inválida. Rust te protege contra este tipo de error saliendo inmediatamente en lugar de permitir el acceso a la memoria y continuar. El Capítulo 9 discute más sobre el manejo de errores de Rust y cómo puedes escribir código legible y seguro que no entre en pánico ni permita el acceso a memoria inválida.
El programa dio lugar a un *error en tiempo de ejecución* al momento de utilizar
un valor no válido en la operación de indexación. El programa salió con un
mensaje de error y no ejecutó la sentencia final `println!`. Cuando intentas
acceder a un elemento utilizando la indexación, Rust comprobará que el índice
que has especificado es menor que la longitud del array. Si el índice es mayor o
igual que la longitud, Rust entrará en pánico. Esta comprobación tiene que
ocurrir en tiempo de ejecución, especialmente en este caso, porque el compilador
no puede saber qué valor introducirá el usuario cuando ejecute el código más
tarde.

Este es un ejemplo de los principios de seguridad de memoria de Rust en acción.
En muchos lenguajes de bajo nivel, este tipo de comprobación no se hace, y
cuando proporcionas un índice incorrecto, se puede acceder a memoria inválida.
Rust te protege contra este tipo de error saliendo inmediatamente en lugar de
permitir el acceso a la memoria y continuar. El Capítulo 9 discute más sobre el
manejo de errores de Rust y cómo puedes escribir código legible y seguro que no
entre en pánico ni permita el acceso a memoria inválida.

[comparing-the-guess-to-the-secret-number]: ch02-00-guessing-game-tutorial.html#comparando-la-adivinanza-con-el-numero-secreto
[twos-complement]: https://es.wikipedia.org/wiki/Complemento_a_dos
Expand Down
18 changes: 9 additions & 9 deletions src/ch03-05-control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,26 +324,26 @@ muestra cada elemento en el arreglo `a`.

</Listing>

Aquí, el código cuenta hacia arriba a través de los elementos en la matriz. Se
Aquí, el código cuenta hacia arriba a través de los elementos en el arreglo. Se
inicia en el índice `0`, y luego se ejecuta hasta que alcanza el índice final
en la matriz (es decir, cuando `index < 5` ya no es `true`). Ejecutar este
código imprimirá cada elemento en la matriz:
en el arreglo (es decir, cuando `index < 5` ya no es `true`). Ejecutar este
código imprimirá cada elemento en el arreglo:

```console
{{#include ../listings/ch03-common-programming-concepts/listing-03-04/output.txt}}
```

Todos los cinco valores de la matriz aparecen en la terminal, como se esperaba.
Los cinco valores del arreglo aparecen en la terminal, como se esperaba.
Aunque `index` llegará a un valor de `5` en algún momento, el bucle deja de
ejecutarse antes de intentar obtener un sexto valor de la matriz.
ejecutarse antes de intentar obtener un sexto valor del arreglo.

Sin embargo, este enfoque es propenso a errores; podríamos causar que el
programa se descomponga si el valor del índice o la condición de prueba es
incorrecta. Por ejemplo, si cambia la definición de la matriz `a` para tener
incorrecta. Por ejemplo, si cambia la definición del arreglo `a` para tener
cuatro elementos, pero olvida actualizar la condición a `while index < 4`, el
código se descompondría. También es lento, porque el compilador agrega código
de tiempo de ejecución para realizar la verificación condicional de si el
índice está dentro de los límites de la matriz en cada iteración del bucle.
índice está dentro de los límites del arreglo en cada iteración del bucle.

Como una alternativa más concisa, puede usar un bucle `for` y ejecutar algún
código para cada elemento en una colección. Un bucle `for` se ve como el código
Expand All @@ -360,10 +360,10 @@ en el Listado 3-5.
Cuando ejecutamos este código, veremos la misma salida que en el Listado 3-4.
Lo más importante es que ahora hemos aumentado la seguridad del código y
eliminado la posibilidad de errores que podrían deberse a ir más allá del final
de la matriz o no ir lo suficientemente lejos y perder algunos elementos.
del arreglo o no ir lo suficientemente lejos y perder algunos elementos.

Usando el bucle `for`, no necesitaría recordar cambiar cualquier otro código si
cambiara el número de valores en la matriz, como lo haría con el método usado en
cambiara el número de valores en el arreglo, como lo haría con el método usado en
el Listado 3-4.

La seguridad y concisión de los bucles `for` los convierten en la
Expand Down
5 changes: 2 additions & 3 deletions src/ch08-02-strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,8 @@ Como resultado, `s` contendrá `lol`.

#### Concatenacion con el operador `+` o la Macro `format!`

A veces, necesitarás combinar dos strings. Sin embargo, no es tan simple como
usar el operador `+` con dos referencias a `String`. El código en el listado
8-18 no compilará:
A menudo, querrás combinar dos cadenas existentes. Una forma de hacerlo es
usar el operador `+`, como se muestra en el Listado 8-18.

<Listing number="8-18" caption="Usando el operador `+` para combinar dos valores `String` en un nuevo valor `String`">

Expand Down
2 changes: 1 addition & 1 deletion src/ch09-00-error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Rust agrupa los errores en dos categorías principales: errores *recuperables* e
encontrado*, lo más probable es que solo queramos informar el problema al
usuario y volver a intentar la operación. Los errores irreversibles siempre son
síntomas de errores, como intentar acceder a una ubicación más allá del final
de una matriz, por lo que queremos detener inmediatamente el programa.
de un arreglo, por lo que queremos detener inmediatamente el programa.

La mayoría de los lenguajes no distinguen entre estos dos tipos de errores y los
manejan de la misma manera, utilizando mecanismos como excepciones. Rust no
Expand Down
2 changes: 1 addition & 1 deletion src/ch09-01-unrecoverable-errors-with-panic.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A veces, sucede algo malo en su código y no hay nada que pueda hacer al
respecto. En estos casos, Rust tiene la macro `panic!`. Hay dos formas de causar
un panic en la práctica: tomando una acción que hace que nuestro código entre en
pánico (como acceder a una matriz más allá del final) o llamando explícitamente
pánico (como acceder a un arreglo 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, se desharán,
limpiarán la pila y se cerrarán. A través de una variable de entorno, también
Expand Down
32 changes: 17 additions & 15 deletions src/ch10-01-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ concretos diferentes. Primero veamos cómo definir funciones, structs,
enums y métodos usando genéricos. Luego discutiremos cómo los genéricos
afectan el rendimiento del código.

### Definiciones in function
### Definiciones En Function

Al definir una función que usa genéricos, colocamos los genéricos en la firma de
la función donde normalmente especificaríamos los tipos de datos de los
Expand Down Expand Up @@ -44,7 +44,7 @@ Cuando usamos un parámetro en el cuerpo de la función, tenemos que declarar el
nombre del parámetro en la firma para que el compilador sepa qué significa ese
nombre. De manera similar, cuando usamos un nombre de parámetro de tipo en la
firma de una función, tenemos que declarar el nombre del parámetro de tipo
antes de usarlo. Para definir la función genérico `largest`, coloque las
antes de usarlo. Para definir un genérico en la función `largest`, coloque las
declaraciones de nombre de tipo dentro de corchetes angulares, `<>`, entre el
nombre de la función y la lista de parámetros, así:

Expand All @@ -58,7 +58,7 @@ de tipo `T`. La función `largest` devolverá una referencia a un valor del mism
tipo `T`.

El listado 10-5 muestra la definición de la función `largest` combinada usando
el tipo de datos genérico en su firma. La lista también muestra cómo podemos
el tipo de datos genéricos en su firma. La lista también muestra cómo podemos
llamar a la función con un slice de valores `i32` o valores `char`. Tenga en
cuenta que este código aún no se compilará, pero lo arreglaremos más adelante
en este capítulo.
Expand Down Expand Up @@ -89,7 +89,7 @@ restringimos los tipos válidos para `T` solo a aquellos que implementan
`PartialOrd` y este ejemplo se compilará, porque la biblioteca estándar
implementa `PartialOrd` tanto en `i32` como en `char`.

### Definiciones In Struct
### Definiciones En Struct

También podemos definir structs para usar tipos genéricos en uno o más campos
usando la sintaxis `<>`. El listado 10-6 define un struct `Point<T>` para
Expand Down Expand Up @@ -150,12 +150,12 @@ generic sobre los tipos `T` y `U` donde `x` es de tipo `T` y `y` es de tipo
¡Ahora todas las instancias de `Point` que se muestran se permiten! Puede usar
tantos parámetros de tipo genérico en una definición como desee, pero usar más
de unos pocos hace que su código sea difícil de leer. Si encuentra que necesita
muchos tipos genérico en su código, podría indicar que su código necesita
muchos tipos genéricos en su código, podría indicar que su código necesita
reestructurarse en piezas más pequeñas.

### Definiciones In Enum
### Definiciones En Enum

Como hicimos con structs, podemos definir enums para contener tipos genérico en
Como hicimos con structs, podemos definir enums para contener tipos genéricos en
sus variantes. Echemos otro vistazo al enum `Option<T>` que la biblioteca
estándar proporciona, que usamos en el Capítulo 6:

Expand All @@ -173,7 +173,7 @@ Al usar el enum `Option<T>`, podemos expresar el concepto abstracto de un valor
opcional, y porque `Option<T>` es genérico, podemos usar esta abstracción sin
importar el tipo del valor opcional.

Los enums también pueden usar múltiples tipos genérico. La definición del enum
Los enums también pueden usar múltiples tipos genéricos. La definición del enum
`Result` que usamos en el Capítulo 9 es un ejemplo:

```rust
Expand All @@ -195,11 +195,11 @@ usamos para abrir un archivo en el listado 9-3, donde `T` se llenó con el tipo

Cuando reconoces situaciones en tu código con múltiples definiciones de struct
o enum que difieren solo en los tipos de los valores que contienen, puedes
evitar la duplicación usando tipos genérico en su lugar.
evitar la duplicación usando tipos genéricos en su lugar.

### Definiciones In Method
### Definiciones En Method

Podemos implementar métodos en structs y enums y usar tipos genérico en sus
Podemos implementar métodos en structs y enums y usar tipos genéricos en sus
definiciones también. El listado 10-9 muestra el struct `Point<T>` que
definimos en el listado 10-6 con un método llamado `x` implementado en él.

Expand All @@ -225,7 +225,7 @@ escritos dentro de un `impl` que declara el tipo genérico se definirán en
cualquier instancia del tipo, sin importar qué tipo concreto termine
sustituyendo al tipo genérico.

También podemos especificar restricciones en los tipos genérico al definir
También podemos especificar restricciones en los tipos genéricos al definir
métodos en el tipo. Por ejemplo, podríamos implementar métodos solo en
instancias de `Point<T>` con un tipo `f32` concreto en lugar de en instancias
de `Point<T>` con cualquier tipo genérico. En el listado 10-10 usamos el tipo
Expand All @@ -248,7 +248,7 @@ matemáticas que solo están disponibles para tipos de punto flotante.

Los parámetros de tipo genérico en una definición de struct no siempre son los
mismos que los que usas en las firmas de métodos de ese mismo struct. El
listado 10-11 usa los tipos genérico `X1` e `Y1` para el struct `Point` y `X2`
listado 10-11 usa los tipos genéricos `X1` e `Y1` para el struct `Point` y `X2`
`Y2` para la firma del método `mixup` para hacer el ejemplo más claro. El
método crea una nueva instancia de `Point` con el valor `x` del `self` `Point`
(de tipo `X1`) y el valor `y` del `Point` pasado (de tipo `Y2`).
Expand Down Expand Up @@ -276,10 +276,12 @@ del método. Aquí, los parámetros genérico `X1` e `Y1` se declaran después d
`Y2` se declaran después de `fn mixup`, porque solo son relevantes para el
método.

### Rendimiento de codigo usando genericos
<a id="rendimiento-de-codigo-usando-genericos"></a>

### Rendimiento de código usando genéricos

Quizás te estés preguntando si hay un costo de rendimiento al usar parámetros
de tipo genérico. La buena noticia es que usar tipos genérico no hará que tu
de tipo genérico. La buena noticia es que usar tipos genéricos no hará que tu
programa se ejecute más lento de lo que lo haría con tipos concretos.

Rust logra esto realizando _monomorfización_ del código usando genéricos en
Expand Down
Loading

0 comments on commit 66406b7

Please sign in to comment.