Restricciones de Tipo de Genéricos en Rust

RustRustBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, al trabajar con genéricos en Rust, los parámetros de tipo deben estar limitados por traits para especificar la funcionalidad que un tipo debe implementar.

Nota: Si el laboratorio no especifica un nombre de archivo, puede usar cualquier nombre de archivo que desee. Por ejemplo, puede usar main.rs, compilar y ejecutarlo con rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/traits("Traits") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} rust/floating_types -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} rust/function_syntax -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} rust/expressions_statements -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} rust/method_syntax -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} rust/traits -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} rust/operator_overloading -.-> lab-99348{{"Restricciones de Tipo de Genéricos en Rust"}} end

Límites

Al trabajar con genéricos, los parámetros de tipo a menudo deben usar traits como límites para especificar qué funcionalidad implementa un tipo. Por ejemplo, el siguiente ejemplo utiliza el trait Display para imprimir y por lo tanto requiere que T esté limitado por Display; es decir, T debe implementar Display.

// Define una función `printer` que toma un tipo genérico `T` que
// debe implementar el trait `Display`.
fn printer<T: Display>(t: T) {
    println!("{}", t);
}

Establecer límites restringe el genérico a tipos que cumplen con los límites. Es decir:

struct S<T: Display>(T);

// Error! `Vec<T>` no implementa `Display`. Esta
// especialización fallará.
let s = S(vec![1]);

Otro efecto de establecer límites es que se permite a las instancias genéricas acceder a los [métodos] de los traits especificados en los límites. Por ejemplo:

// Un trait que implementa el marcador de impresión: `{:?}`.
use std::fmt::Debug;

trait HasArea {
    fn area(&self) -> f64;
}

impl HasArea for Rectangle {
    fn area(&self) -> f64 { self.length * self.height }
}

#[derive(Debug)]
struct Rectangle { length: f64, height: f64 }
#[allow(dead_code)]
struct Triangle  { length: f64, height: f64 }

// El genérico `T` debe implementar `Debug`. Independientemente
// del tipo, esto funcionará correctamente.
fn print_debug<T: Debug>(t: &T) {
    println!("{:?}", t);
}

// `T` debe implementar `HasArea`. Cualquier tipo que cumpla
// con el límite puede acceder a la función `area` de `HasArea`.
fn area<T: HasArea>(t: &T) -> f64 { t.area() }

fn main() {
    let rectangle = Rectangle { length: 3.0, height: 4.0 };
    let _triangle = Triangle  { length: 3.0, height: 4.0 };

    print_debug(&rectangle);
    println!("Area: {}", area(&rectangle));

    //print_debug(&_triangle);
    //println!("Area: {}", area(&_triangle));
    // ^ TODO: Intentar descomentar estos.
    // | Error: No implementa ni `Debug` ni `HasArea`.
}

Como nota adicional, en algunos casos también se pueden usar cláusulas where para aplicar límites y ser más expresivos.

Resumen

¡Felicitaciones! Has completado el laboratorio de Límites. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.