Reduzca la huella de su código Rust y aumente su robustez con tipos genéricos.

Siempre hay niveles de incertidumbre al desarrollar aplicaciones, lo que puede generar errores, especialmente si sus funciones aceptan tipos específicos de argumentos. Para reducir los errores debidos a incertidumbres, puede utilizar Genéricos. Los genéricos proporcionan funcionalidad para crear clases, funciones y estructuras de datos para trabajar con diferentes tipos.

Con genéricos, puede crear y definir algoritmos y estructuras de datos que pueden operar en múltiples tipos sin escribir código complejo e implementaciones separadas para cada tipo. Los genéricos mejoran la reutilización y la eficiencia del código al tiempo que mantienen la seguridad y el rendimiento de los tipos.

Uso de tipos genéricos en Rust

El tipo genérico de Rust puede interoperar con otros tipos de datos de Rust. Definirá tipos genéricos con corchetes angulares (<>), seguidos de dos o más parámetros.

Aquí hay un genérico definición de estructura que toma dos parámetros de tipo genérico:

instagram viewer
estructuraPunto {
// T y U son parámetros de tipo genérico que los campos x e y
// asumir en instanciación
x: T,
Yu,
}

En el Punto estructura, T, y tu son parámetros de tipo genérico.

Puede reemplazar los parámetros de tipo genérico con cualquier tipo de datos en la creación de instancias:

fnprincipal() {
dejar mi_punto = Punto { x: Cadena::de("Hola"), y: Cadena::de("mundo") };

imprimir!(
"El valor x de my_point es {} y el valor y es {}".,
mi_punto.x,
mi_punto.y
);
}

El mi punto variable es una instancia de la Punto estructura inicializada con tipos de cadena. El compilador de Rust infiere los tipos concretos de T y tu basado en los valores en la creación de instancias.

Límites de características para tipos genéricos

Los tipos genéricos de Rust pueden usar límites de rasgos para garantizar la seguridad del tipo. Los rasgos son colecciones de métodos que los tipos pueden implementar para exhibir ciertos comportamientos definidos para el rasgo.

Los límites de rasgos especifican que un tipo genérico debe implementar uno o más rasgos.

Aquí hay un ejemplo de una función genérica que devuelve el mayor de dos valores con un límite de rasgo que asegura que los tipos comparados implementen el rasgo:

// Máximo es un rasgo que define un método para evaluar el máximo de dos
// tipos
rasgoMáximo {
fnmáximo(ser, otro: Ser) -> Ser;
}

// Implementa el rasgo `Máximo` para todos los tipos que implementan el
// rasgo `PartialOrd`.
implParcialOrd> Máximo para T {
fnmáximo(ser, otro: Ser) -> Ser {
// devuelve `self` si es mayor que `other`; de lo contrario, regresa
// `otro.`
siser > otro {
ser
} demás {
otro
}
}
}

fnprincipal() {
dejar un = 5;
dejar segundo = 10;
dejar mayor = Máximo:: max (a, b);
imprimir!("El valor más grande es {}", más grande);
}

El Máximo rasgo tiene un máximo método que devuelve el mayor de dos valores del mismo tipo. Cualquier tipo que implemente el ParcialOrd rasgo implementa el Máximo rasgo.

El máximo método toma dos valores de la Ser tipo—refiriéndose al tipo que implementa el Máximo rasgo—y compara los valores.

El principal La función compara dos variables usando el máximo e imprime el más grande.

Restricciones para tipos genéricos

Las restricciones son similares a los límites de rasgos, pero le permiten especificar requisitos adicionales en los tipos que está utilizando como parámetros de tipo.

Si desea crear una función genérica que acepte tipos para la conversión de cadenas, puede usar una restricción para garantizar que el parámetro de tipo implemente un rasgo.

// ToString es un rasgo con un método de conversión de cadena
rasgoEncadenar {
fnEncadenar(&ser) -> Cadena;
}

// to_string es una función genérica que toma un valor de cualquier tipo que
// implementa el rasgo ToString
fnEncadenarEncadenar>(valor: T) -> Cadena {
valor.a_cadena()
}

El Encadenar El parámetro de valor debe implementar el Encadenar rasgo, lo que garantiza que puede convertir valores de tipo T para enhebrar con el Encadenar método.

Los tipos genéricos son útiles para trabajar con rasgos

Los tipos genéricos de Rust son poderosos y hay áreas para mejorar. Un área crítica de enfoque es mejorar el rendimiento del código genérico. Actualmente, el sistema de tipos de Rust puede imponer una sobrecarga en el código genérico, lo que ralentiza el rendimiento.

Los tipos genéricos son beneficiosos para trabajar con características. Al usar tipos genéricos, puede crear objetos de rasgos que funcionen con cualquier tipo que implemente un rasgo para que sus métodos sean más flexibles.