Galería de mapas mentales Dominando RUST 2da edición
Este es un mapa mental sobre cómo dominar RUST. A través de los pasos y sugerencias anteriores, puede mejorar gradualmente sus habilidades de programación en Rust y disfrutar de la seguridad de la memoria y el rendimiento eficiente que brinda Rust.
Editado a las 2024-04-04 15:14:48,La seconda unità del corso obbligatorio di biologia ha riassunto e organizzato i punti di conoscenza, coprendo tutti i contenuti principali, il che è molto comodo da apprendere per tutti. Adatto per la revisione e l'anteprima degli esami per migliorare l'efficienza dell'apprendimento. Affrettati a ritirarlo per imparare insieme!
Questa è una mappa mentale sull'estrazione e la corrosione del me. Il contenuto principale include: corrosione dei metalli, estrazione dei metalli e serie di reattività.
Questa è una mappa mentale sulla reattività dei metalli. Il contenuto principale include: reazioni di spostamento dei metalli, serie di reattività dei metalli.
La seconda unità del corso obbligatorio di biologia ha riassunto e organizzato i punti di conoscenza, coprendo tutti i contenuti principali, il che è molto comodo da apprendere per tutti. Adatto per la revisione e l'anteprima degli esami per migliorare l'efficienza dell'apprendimento. Affrettati a ritirarlo per imparare insieme!
Questa è una mappa mentale sull'estrazione e la corrosione del me. Il contenuto principale include: corrosione dei metalli, estrazione dei metalli e serie di reattività.
Questa è una mappa mentale sulla reattività dei metalli. Il contenuto principale include: reazioni di spostamento dei metalli, serie di reattività dei metalli.
Competente en óxido
Capítulo 1 Comenzando con Rust
1.1 ¿Qué es Rust y por qué lo necesitas?
Rust es un lenguaje de programación rápido, altamente concurrente, seguro y empoderador creado y lanzado originalmente en 2006 por Graydon Hoare. Ahora es un lenguaje de código abierto, mantenido y desarrollado principalmente por el equipo de Mozilla y muchos miembros de la comunidad de código abierto.
Rust tiene un sitio web de desarrollo de código abierto en GitHub y su impulso de desarrollo es muy rápido. Se agregan nuevas funciones al lenguaje a través de un proceso de Solicitud de comentarios (RFC) impulsado por la comunidad, donde cualquiera puede enviar nuevas funciones y luego describirlas en detalle en un documento RFC. Luego se busca consenso sobre el RFC y, si se logra, la función entra en la fase de implementación.
Rust existe como un lenguaje estático y fuertemente tipado. Los atributos estáticos significan que el compilador tiene información sobre todas las variables y tipos relevantes en el momento de la compilación, y realiza muchas comprobaciones en el momento de la compilación, dejando solo una pequeña cantidad de verificación de tipos en el tiempo de ejecución.
1.2 Instale la cadena de herramientas Rust
Rustup.rs
1.3 Introducción a Rust
1.3.1 Tipos primitivos
booleano
Estos son valores booleanos comunes que pueden ser verdaderos o falsos.
carbonizarse
personaje
entero
Este tipo se caracteriza por el ancho de la broca. La longitud máxima admitida por Rust es de 128 bits.
tamaño
Un entero con signo de tamaño variable (el tamaño depende del tamaño del puntero subyacente).
usar
Entero sin signo de tamaño variable (el tamaño depende del tamaño del puntero subyacente).
f32
ftipo de punto flotante de 32 bits
f64
Tipo de punto flotante de 64 bits
[T;norte]
Una matriz de tamaño fijo, T representa el tipo de elemento, N representa el número de elementos y es una constante no negativa en el momento de la compilación.
[t]
Una vista de tamaño dinámico de una secuencia contigua, donde T representa cualquier tipo.
cadena
Corte de cadenas, utilizado principalmente como referencia, es decir, &str
(T, U, ..)
Las sucesiones finitas, T y U, pueden ser de diferentes tipos.
fn(i32)->i32
Una función que recibe un parámetro de tipo i32 y devuelve un parámetro de tipo i32. Las funciones también tienen un tipo.
1.3.2 Declaración de variables e inmutabilidad
En Rust, usamos la palabra clave let para declarar variables. Una vez inicializada una variable, no se le puede asignar otro valor. Si luego necesita apuntar la variable a otra variable (del mismo tipo), debe anteponerla con la palabra clave mut.
1.3.3 Función
Las funciones abstraen un montón de instrucciones en entidades con nombre que luego se pueden llamar desde otro código y ayudan a los usuarios a gestionar la complejidad.
fn agregar (a: u64, b: u64) -> u64 { un segundo } fn principal() { sea a: u64 = 17; sea b = 3; let resultado = agregar(a, b); println!("Resultado {}", resultado); }
Las funciones son básicamente expresiones que devuelven un valor, que de forma predeterminada es un valor de tipo () (unidad), que es similar al tipo de retorno nulo en C/C++.
1.3.4 Cierre
El óxido soporta cierres. Los cierres son similares a las funciones pero tienen más información sobre el entorno o alcance en el que se declaran. Si bien las funciones tienen un nombre asociado, las definiciones de cierres no, pero se pueden asignar a variables. Otra ventaja de la inferencia de tipos de Rust es que en la mayoría de los casos puedes especificar parámetros para cierres sin tipos. Este es el cierre más simple "let my_closure = ||();". Definimos un cierre sin parámetros que no hace nada. Luego podemos llamarlo mediante my_closure(), que es similar a una función. Las dos barras verticales "||" se utilizan para almacenar parámetros de cierre, como |a, b|. A veces es necesario especificar el tipo de parámetro (|a:u32|) cuando Rust no puede encontrar el tipo correcto.
fn principal() { sea duplicador = |x| x * 2; dejar valor = 5; let two = doubler(valor); println!("{} duplicado es {}", valor, dos veces); dejar big_closure = |b, c| sea z = bc; z * dos veces }; let some_number = big_closure(1, 2); println!("Resultado del cierre: {}", algún_número); }
1.3.5 Cadena
String es uno de los tipos de datos más utilizados en cualquier lenguaje de programación. En Rust, suelen aparecer en dos formas: tipo &str y tipo String. Se garantiza que las cadenas Rust son secuencias de bytes codificadas en UTF-8 válidas. No tienen terminación NULL como las cadenas C y pueden contener bytes nulos entre cadenas.
fn principal() { let pregunta = "¿Cómo estás?"; dejar persona: String = "Bob".to_string(); let namaste = String::from("zd"); println!("{}! {} {}", nombre, pregunta, persona); }
En el código anterior, el tipo de persona y namaste es String y el tipo de pregunta es &str. Hay muchas formas de crear datos de tipo String. Los datos de tipo cadena se asignan en el montón. Los datos de tipo &str suelen ser un puntero a una cadena existente. Estas cadenas están en la pila y el montón, o pueden ser cadenas en el segmento de datos del código objeto compilado.
1.3.6 Condiciones y juicios
Los juicios condicionales en Rust son similares a los de otros lenguajes. También siguen una estructura if else similar a C.
fn principal() { let Rust_is_awesome = verdadero; si el óxido_es_increíble { println!("Efectivamente"); } demás { println!("Bueno, ¡deberías probar Rust!"); } }
En Rust, la construcción if no es una declaración, sino una expresión. En el lenguaje general de programación, las declaraciones no devuelven ningún valor, pero las expresiones sí. Esta distinción significa que las condiciones if else en Rust siempre devuelven un valor. El valor puede ser de tipo vacío () o un valor real. Cualquiera que sea la última línea de llaves, se convierte en el valor de retorno de la expresión if else. Es importante tener en cuenta que las ramas if y else deben tener el mismo tipo de devolución.
fn principal() { deja resultado = si 1 == 2 { "¿Esperar lo?" } demás { "El óxido tiene sentido" }; println!("¿Sabes qué? {}.", resultado); }
Cuando el valor a asignar se devuelve de la expresión if else, necesitamos usar un punto y coma como marca final. Por ejemplo, si es una expresión, entonces let es una declaración, que espera que tengamos un punto y coma al final.
1.3.7 expresión de coincidencia
Las expresiones de coincidencia de Rust son muy simples y fáciles de usar. Es básicamente similar a una versión simplificada de la declaración de cambio en lenguaje C, que permite a los usuarios emitir juicios en función del valor de la variable y si existe una funcionalidad de filtrado avanzada.
fn req_status() -> u32 { 200 } fn principal() { dejar estado = req_status(); estado del partido { 200 => println!("Éxito"), 404 => println!("No encontrado"), otro => { println!("La solicitud falló con el código: {}", otro); } } }
Cada coincidencia debe devolver el mismo tipo. Además, debemos realizar una coincidencia exacta de todos los valores coincidentes posibles. Rust nos permite ignorar las posibilidades restantes mediante el uso de capturar todas las variables (aquí otras) o _ (guión bajo).
1.3.8 Bucle
Se puede hacer algo repetidamente en Rust usando 3 construcciones, a saber, loop, while y for. En todas estas construcciones, las palabras clave continuar y romper generalmente se incluyen, lo que le permite saltarse y salir del bucle respectivamente.
fn principal() { sea mut x = 1024; bucle { si x < 0 { romper; } println!("{} quedan más ejecuciones", x); x-= 1; } }
Una característica adicional de ejecutar bucles en Rust es la capacidad de etiquetar bloques de código de bucle con nombres. Esto se puede usar en situaciones en las que tiene dos o más bucles anidados y desea salir de cualquiera de ellos, no solo para bucles que contienen directamente declaraciones de interrupción.
fn tonto_sub (a: i32, b: i32) -> i32 { dejar resultado mut = 0; 'incremento: bucle { si resultado == a { sea mut dec = b; 'decremento: bucle { ifdec==0{ romper 'incremento; } demás { resultado -= 1; diciembre -= 1; } } } demás { resultado = 1; } } resultado } fn principal() { sea a = 10; sea b = 4; let resultado = tonto_sub(a, b); println!("{} menos {} es {}", a, b, resultado); }
Rust también tiene la palabra clave for, que es similar al bucle for utilizado en otros lenguajes, pero su implementación es completamente diferente. El bucle for de Rust es básicamente azúcar sintáctico para una construcción de iteración más poderosa (iterador). En pocas palabras, los bucles for en Rust solo funcionan con tipos que se pueden convertir en iteradores. Uno de esos tipos es el tipo Rango. El tipo de Rango puede hacer referencia a una serie de números.
fn principal() { imprimir!("Rango normal: "); para i en 0..10 { imprimir!("{},", i); } imprimir!(); print!("Rango inclusivo: "); para i en 0..=10 { imprimir!("(),", i); } }
1.3.9 Tipos de datos personalizados
Los tipos personalizados son tipos definidos por los usuarios. Los tipos personalizados pueden estar compuestos de varios tipos. Pueden ser envoltorios de tipos primitivos o una combinación de múltiples tipos personalizados. Vienen en tres formas: estructura, enumeración y unión, también conocidas como estructura, enumeración y unión. Le permiten representar sus datos más fácilmente. Las reglas de nomenclatura para tipos personalizados siguen CamelCase.
Estructura
En Rust, existen tres formas de declaración de estructura. La más simple de ellas es la estructura unitaria, que se declara utilizando la palabra clave struct, seguida de su nombre y termina con un punto y coma.
estructura ficticia; fn principal() { let valor = ficticio; }
La segunda forma de estructura es la estructura de tupla, que tiene datos asociados. Cada uno de estos campos no tiene nombre, pero se hace referencia a ellos según su posición en la definición.
Color de estructura (u8, u8, u8); fn principal() { dejar blanco = Color(255, 255, 255); sea rojo = blanco.0; deja verde = blanco.1; sea azul = blanco.2; println!("Valor rojo: {}", rojo); deja naranja = Color(255, 165, 0); sea Color(r, g, b) = naranja; println!("R: {}, G: {}, B: {} (naranja)", r, g, b); let Color(r, _, b) = naranja; }
Las estructuras de tuplas son ideales para modelar datos con menos de 5 atributos. Cualquier elección distinta a esta obstaculizará la legibilidad y el razonamiento del código. Para tipos de datos con más de 3 campos, construya estructuras utilizando un lenguaje similar a C. Esta es la tercera forma y la más utilizada.
estructura jugador { nombre: cadena, coeficiente intelectual: u8, amigos: u8, puntuación: sub16 } fn knock_player_score(mut jugador: Jugador, puntuación: u16) { jugador.puntuación = puntuación; println!("Estadísticas del jugador actualizadas:"); } fn principal() { let nombre = "Alicia".to_string(); dejar jugador = Jugador { nombre, coeficiente intelectual: 171, amigos: 134, puntuación: 1129 }; knock_player_score(jugador, 120); }
enumerar
Las enumeraciones son una buena manera de hacer esto cuando necesitas modelar diferentes tipos de cosas. Se crea utilizando la palabra clave enum, seguida del nombre de la enumeración y un par de llaves. Dentro de las llaves podemos escribir todos los tipos posibles, es decir, variantes. Estas variantes se pueden definir con o sin datos, y los datos contenidos pueden ser de cualquier tipo, estructura, estructura de tupla o incluso un tipo de enumeración.
enumeración Dirección { NORTE, MI, S, W. } enumeración AcciónReproductor { Mover { dirección: Dirección, Velocidad: u8 }, Esperar, Ataque (Dirección) } fn principal() { let simulado_player_action = PlayerAction::Mover { dirección: Dirección::N, velocidad: 2, }; coincide con la acción_jugador_simulada { PlayerAction::Wait => println!("El jugador quiere esperar"), PlayerAction::Mover { dirección, velocidad } => { println!("El jugador quiere moverse en la dirección {:?} con velocidad {}", dirección, velocidad) } PlayerAction::Ataque(dirección) => { println!("El jugador quiere acceder a la dirección {:?}", dirección) } }; }
1.3.10 Funciones y métodos sobre tipos.
bloque impl en estructura
Podemos agregar comportamiento a una estructura definida usando dos mecanismos: funciones tipo constructor y métodos getter y setter.
estructura jugador { nombre: cadena, coeficiente intelectual: u8, amigos:u8 } jugador implícito { fn with_name(nombre: &str) -> Jugador { Jugador { nombre: nombre.to_string(), coeficiente intelectual: 100, amigos: 100 } } fn get_friends(&self) -> u8 { mis.amigos } fn establecer amigos (&mut self, contar: u8) { self.friends = contar; } } fn principal() { let mut jugador = Jugador::with_name("Dave"); jugador.set_friends(23); println!("Los amigos de {} cuentan: {}", player.name, player.get_friends()); let _ = Jugador::get_friends(&player); }
Método asociado: este método no tiene el tipo propio como primer parámetro. Es similar a los métodos estáticos en los lenguajes de programación orientados a objetos. Estos métodos se pueden llamar en el tipo mismo y no requieren que se llame a una instancia del tipo. Se llama a un método asociado precediendo el nombre del método con el nombre de la estructura y dos puntos dobles.
Método de instancia: una función que se toma a sí misma como primer parámetro externo. El self aquí es similar al self en Python y apunta a la instancia que implementa el método.
bloques impl y enumeraciones
Las enumeraciones se usan ampliamente en máquinas de estado y, cuando se usan con expresiones de coincidencia, pueden hacer que el código de transición de estado sea muy conciso. También se pueden utilizar para modelar tipos de errores personalizados.
enum Modo de pago { Débito, Crédito, PayPal } fn pay_by_credit(imt: u64) { println!("Procesando pago de crédito de {}", amt); } fn pay_by_debit(cantidad: u64) { println!("Procesando pago de débito de {}", amt); } fn paypal_redirect(cantidad: u64) { println!("Redireccionando a paypal por importe: {}", amt); } implica modo de pago { fn pagar(&self, monto: u64) { coincidir con uno mismo { Modo de pago::Débito => pay_by_debit(monto), Modo de pago::Crédito => pay_by_credit(monto), Modo de pago::Paypal => paypal_redirect(monto) } } } fn get_saved_paid_mode() -> Modo de pago { Modo de pago::Débito } fn principal() { dejar modo_pago = get_saved_pago_mode(); modo_pago.pay(512); }
1.3.11 módulo, declaraciones de importación y uso
Los lenguajes de programación suelen proporcionar una forma de dividir grandes bloques de código en varios archivos para gestionar la complejidad. Java sigue la convención de que cada archivo .java es una clase pública y C nos proporciona archivos de encabezado y declaraciones de inclusión. Rust proporciona un mecanismo de módulo. Los módulos son una forma de nombrar y organizar el código en los programas Rust.
Cada programa Rust requiere un módulo raíz. Para los archivos ejecutables, suele ser el archivo main.rs y, para las bibliotecas, suele ser el archivo lib.rs.
Los módulos pueden declararse dentro de otros módulos u organizarse en archivos y directorios.
Para que el compilador reconozca nuestro módulo, debemos usar la declaración mod de palabra clave. En nuestro módulo raíz, debemos usar la palabra clave use antes del nombre del módulo, lo que significa incluir el elemento en el alcance.
Los elementos definidos en un módulo son privados de forma predeterminada y deben exponerse a las personas que llaman mediante la palabra clave pub.
1.3.12 Colección
formación
Las matrices tienen una longitud fija y pueden almacenar elementos del mismo tipo. Están representadas por [T, N], donde T representa cualquier tipo y N representa el número de elementos de la matriz. El tamaño de la matriz no puede representarse mediante una variable y debe ser un valor literal de uso.
tupla
Lista de proyectos
par clave/valor
rebanada
1.3.13 Iterador
subtema
subtema
subtema
1.4 Mejorar el contador de personajes
1.5 Resumen
Capítulo 2 Uso de Cargo para gestionar proyectos
2.1 Administrador de paquetes
2.2 Módulos
2.2.1 Módulos anidados
2.2.2 Usar archivos como módulos
2.2.3 Usar directorios como módulos
2.3 Carga y bibliotecas
2.3.1 Crear un nuevo proyecto de carga
2.3.2 Carga y dependencias
2.3.3 Uso de Cargo para ejecutar pruebas
2.3.4 Uso de Cargo para ejecutar el ejemplo
2.3.5 Espacio de trabajo de carga
2.4 Extensión de herramienta de carga
2.4.1 Instalación de subcomandos y carga
2.4.2 Usar clippy para formatear código
2.4.3 Introducción al archivo de manifiesto Cargo.toml
2.5 Configurar un entorno de desarrollo Rust
2.6 Utilice Cargo para crear el programa imgtool
2.7 Resumen
Capítulo 3 Pruebas, documentación y evaluación comparativa
3.1 Propósito de las pruebas
3.2 Organización de pruebas
3.3 Pruebas unitarias
3.3.1 La primera prueba unitaria
3.3.2 Ejecución de pruebas
3.3.3 Aislar código de prueba
3.3.4 Prueba de falla
3..3.5 Ignorar pruebas
3.4 Pruebas de integración
3.4.1 Primera prueba de integración
3.4.2 Compartir código común
3.5 Documentación
3.5.1 Redacción de documentación
3.5.2 Generar y ver documentos
3.5.3 Documentos alojados
3.5.4 Propiedades del documento
3.5.5 Pruebas documentadas
3.6 Punto de referencia
3.6.1 Herramientas de microevaluación integradas
3.6.2 Evaluación comparativa de la versión estable de Rust
3.7 Escritura y prueba de paquetes de software: simulador de puerta lógica
3.8 Pruebas de integración de CI y Travis CI
3.9 Resumen
Capítulo 4 Tipos, genéricos y rasgos
4.1 Sistemas de tipos y su importancia
4.2 Genéricos
4.2.1 Creando genéricos#
4.2.2 Implementación genérica
4.2.3 Aplicaciones genéricas
4.3 Uso de características para abstraer el comportamiento
4.3.1 Características
4.3.2 Diversas formas de funciones
4.4 Uso de funciones genéricas del paquete: intervalos de funciones
4.4.1 Intervalos característicos de los tipos
4.4.2 Intervalos característicos en funciones genéricas y bloques de código implícitos
4.4.3 Utilice la combinación de funciones " " para formar un intervalo
4.4.4 Intervalo de características y sintaxis de características implícitas
4.5 Introducción a las funciones de la biblioteca estándar
4.6 Usar objetos de rasgos para lograr un verdadero polimorfismo
4.6.1 Distribución
4.6.2 Objetos característicos
4.7 Resumen
Capítulo 5 Gestión y seguridad de la memoria
5.1 Programas y Memoria
5.2 Cómo los programas usan la memoria
5.3 Gestión y clasificación de la memoria.
5.4 Introducción a la asignación de memoria
5.4.1 Pila
5.4.2 Montón
5.5 Defectos en la gestión de la memoria
5.6 Seguridad de la memoria
5.7 Tres principios de seguridad de la memoria
5.7.1 Propiedad
5.7.2 Reutilizar tipos a través de rasgos
5.7.3 Préstamo
5.7.4 Tipos de métodos basados en reglas de préstamo
5.7.5 Ciclo de vida
5.8 Tipos de puntero en Rust
5.8.1 Referencias: punteros seguros
5.8.2 Punteros sin procesar
5.8.3 Punteros inteligentes
5.8.4 Punteros inteligentes contados por referencia
5.8.5 Aplicación de la variabilidad interna
5.9 Resumen
Capítulo 6 Manejo de excepciones
6.1 Introducción al manejo de excepciones
6.2 Excepciones recuperables
6.2.1 Opción
6.2.2 Resultado
6.3 Combinación opción/resultado
6.3.1 Combinadores comunes
6.3.2 Aplicación combinadora
6.3.3 Conversión entre tipos de opción y resultado
6.4 Devolución anticipada y operador "?"
6.5 Excepciones irrecuperables
6.6 Errores personalizados y características de error
6.7 Resumen
Capítulo 7 Conceptos avanzados
7.1 Introducción a los sistemas de tipos
7.1.1 Bloques de código y expresiones
7.1.2 declaración let
7.1.3 Bucles como expresiones
7.1.4 Claridad de tipos y distinción de símbolos en tipos numéricos
7.1.5 Inferencia de tipos
7.1.6 Alias de tipo
7.2 Cadena
7.2.1 Cadena que contiene propiedad - Cadena
7.2.2 Cadena de préstamo——&str
7.2.3 Cortar y trocear hilos
7.2.4 Usar cadenas en funciones
7.2.5 Concatenación de cadenas
7.2.6 Escenarios de aplicación de &str y String
7.3 Valores globales
7.3.1 Constantes
7.3.2 Valores estáticos
7.3.3 Función en tiempo de compilación——const fn
7.3.4 Valores estáticos dinámicos a través de la macro lazy_static
7.4 Iteradores
7.5 Tipos avanzados
7.5.1 Tipos de longitud indefinida
7.5.2 Tipos de funciones
7.5.3 nunca escriba "!" y ejecute la función
7.5.4 Unión
7.5.5 Vaca
7.6 Funciones avanzadas
7.6.1 Tamaño y tamaño
7.6.2 Préstamo y AsRef
7.6.3 Deshuesado
7.6.4 Desde y hacia
7.6.5 Objetos característicos y seguridad de los objetos
7.6.6 Sintaxis general de llamada a función
7.6.7 Reglas de características
7.7 Cierres avanzados
7.7.1 Cierre Fn
7.7.2 Cierre FnMut
7.7.3 Cierre FnOnce
7.8 Constantes en estructuras, enumeraciones y rasgos
7.9 Módulos, rutas e importaciones
7.9.1 Importar
7.9.2 Importar nuevamente
7.9.3 Privacidad
7.10 Patrones y guardias de combinación avanzada
7.10.1 Guardia de partido
7.10.2 Construcción de let avanzada
7.11 Lanzamiento
7.12 Tipos y memoria
7.12.1 Alineación de la memoria
7.12.2 módulo std::mem
7.13 Serialización y deserialización usando serde
7.14 Resumen
Capítulo 8 Concurrencia
8.1 Modelo de ejecución del programa
8.2 Concurrencia
8.2.1 Métodos concurrentes
8.2.2 Defectos
8.3 Concurrencia en Rust
8.3.1 Conceptos básicos de subprocesos
8.3.2 Hilos personalizados
8.3.3 Accediendo a datos en hilos
8.4 Modelo de concurrencia de subprocesos
8.4.1 Modelo de estado compartido
8.4.2 Exclusión mutua
8.4.3 Mutabilidad compartida a través de Arc y Mutex
8.4.4 Comunicación vía mensajería
8.5 Seguridad de hilos en Rust
8.5.1 ¿Qué es la seguridad de subprocesos?
8.5.2 Características de la seguridad del hilo
8.5.3 Enviar
8.5.4 Sincronización
8.6 Implementación de concurrencia usando el modelo de actor
8.7 Otras bibliotecas
8.8 Resumen
Capítulo 9 Macros y metaprogramación
9.1 ¿Qué es la metaprogramación?
9.2 Escenarios de aplicación de macros de Rust
9.3 Macros y sus tipos en Rust
9.4 ¡Crea macros usando macro_rules!
9.5 Macros integradas en la biblioteca estándar
9.6 macro_rules! Tipo de etiqueta macro
9.7 Repetición en macros
9.8 Aplicación avanzada de macros: escritura de DSL para la inicialización de HashMap
9.9 Casos de uso de macros: pruebas de escritura
9.10 Ejercicio
9.11 Macros de proceso
9.12 Macros derivadas
9.13 Macros de alto nivel
9.14 Paquetes de software de macros de procesos de uso común
9.15 Resumen
Capítulo 10 Interfaces inseguras de óxido y funciones extrañas
10.1 Seguridad e inseguridad
10.1.1 Funciones y bloques de código inseguros
10.1.2 Características e implementaciones inseguras
10.2 Llamar al código C en Rust
10.3 Llamar al código Rust a través del lenguaje C
10.4 Uso de bibliotecas C/C externas en Rust
10.5 Construyendo extensiones nativas de Python usando PyO3
10.6 Creando extensiones nativas para Node.js en Rust
10.7 Resumen
Capítulo 11 Registro
11.1 La tala y su importancia
11.2 Requisitos para un marco de registro
11.3 Marco de registro y sus características
11.4 Método de registro
11.4.1 Registro no estructurado
11.4.2 Registro estructurado
11.5 Iniciar sesión en Rust
11.5.1 registro: registro de Rust
11.5.2 env_logger
11.5.3 registro4rs
11.5.4 Uso de slog para registro estructurado
11.6 Resumen
Capítulo 12 Rust y programación de redes
12.1 Introducción a la programación de redes
12.2 E/S de red síncrona
12.3 E/S de red asíncrona
12.3.1 Abstracciones asincrónicas en Rust
12.3.2 Construyendo un servidor Redis asíncrono
12.4 Resumen
Capítulo 13 Creación de aplicaciones web con Rust
13.1 Aplicaciones web en Rust
13.2 Uso de Hyper para comunicación HTTP
13.2.1 La API Hyper del lado del servidor crea un servicio de URL corta
13.2.2 Hyper como cliente: creación de un cliente corto de URL
13.2.3 Marco web
13.3 Conocimientos básicos de Actix-web
13.4 Creación de una API de marcadores utilizando actix-web
13.5 Resumen
Capítulo 14 Rust y WebAssembly
14.1 La importancia de la durabilidad de los datos
14.2 SQLite
14.3 PostgreSQL
14.4 grupo de conexiones r2d2
14.5 Postgres y ORM diésel
14.6 Resumen
Capítulo 15 Rust y WebAssembly
15.1 ¿Qué es WebAssmbly?
15.2 Objetivos de diseño de WebAssembly
15.3 Comenzando con WebAssembly
15.3.1 Pruebe en línea
15.3.2 Métodos para generar WebAssembly
15.4 Óxido y WebAssembly
15.4.1 enlace de wasm
15.4.2 Otros proyectos de WebAssembly
15.5 Resumen
Capítulo 16 Rust y aplicaciones de escritorio
16.1 Introducción al desarrollo de GUI
16.2 Marco GTK
16.3 Cree una aplicación de escritorio de noticias a través de gtk-rs
16.4 Ejercicios
16.5 Otros marcos de UI emergentes
16.6 Resumen
Capítulo 17 Depuración
17.1 Introducción a la depuración
17.1.1 Conceptos básicos del depurador
17.1.2 Requisitos previos para la puesta en servicio
17.1.3 Configurar BGF
17.1.4 Un programa de ejemplo: buggie
17.1.5 Conceptos básicos del BGF
17.1.6 Integración de GDB en Visual Studio Code
17.2 Introducción al depurador rr
17.3 Resumen