Históricamente, uno de los principios de Rust ha sido garantizar la seguridad de tipos y la ausencia de conversiones implícitas que conducen a errores de ejecución. Pero para la comodidad del código, se implementan conversiones automáticas parciales a través de deref coercion y los traits From/Into, para simplificar el trabajo con referencias, punteros inteligentes y permitir APIs universales.
El problema surge cuando las conversiones automáticas pueden causar confusión, por ejemplo, al pasar &String donde se espera &str. Se provoca un Deref::deref oculto, y a veces surgen consecuencias imprevistas (por ejemplo, cuando se cambia el tipo de los parámetros pasados). También existe la cuestión del casting explícito a través de as.
Solución: Rust implementa reglas estrictas de deref-coercion para punteros inteligentes (Box, Rc, Arc) y cadenas (&String a &str, &Vec a &slice) a nivel de compilador. Para las conversiones explícitas, se prevén traits From, Into, TryFrom, TryInto, as para castings básicos. La tipificación estática y la restricción de conversiones implícitas ayudan a evitar errores.
Ejemplo de código:
fn print_text(text: &str) { println!("{}", text); } let s = String::from("¡Hola!"); print_text(&s); // s: String, &s: &String, conversión automática a &str
Características clave:
¿Funciona la deref coercion para tipos propios, si implementas Deref manualmente?
Sí, si implementas el trait Deref para tu tipo, el compilador podrá convertir automáticamente, por ejemplo, tu envoltura en el tipo objetivo dentro de la firma de una función que espera la referencia correspondiente.
¿Puede haber deref coercion para valores, en lugar de referencias?
No, la desreferenciación automática solo ocurre al pasar referencias y solo cuando el tipo implementa Deref.
¿Cuáles son las limitaciones de la conversión de tipos a través de as al trabajar con números y enum?
as no garantiza seguridad: la conversión entre tipos de números puede causar desbordamientos o pérdida de datos, y para enum resultará en valores no semánticos (por ejemplo, en una variante incorrecta de enum).
Un principiante escribe una función que toma &String y no puede usar &str directamente, siempre hace text.to_string() de la cadena. Esto es derrochador en memoria y rendimiento.
Ventajas:
Desventajas:
La función toma un argumento del tipo &str, lo que permite que se llame con cualquier tipo que soporte desreferenciación o conversión: &str, &String, literales de cadena. No se requieren asignaciones innecesarias.
Ventajas:
Desventajas: