Las estructuras son básicamente tipos definidos por el usuario que se utilizan principalmente para agrupar diferentes tipos de datos. Supera la limitación de una array tradicional que solo puede contener elementos del mismo tipo de datos. Una estructura también puede contener una estructura en sí misma. En Rust, las estructuras son similares a las tuplas, pero los elementos de la estructura son fácilmente accesibles ya que se nombran en lugar de indexarse en el caso de las tuplas.
En Rust, las estructuras son de tres tipos.
- Estructura típica tipo C
- Estructura de tupla: es similar a una tupla, donde los campos no tienen nombre pero tienen funcionalidades adicionales.
- Estructura de unidad: estas son estructuras sin campo, es decir, no contienen datos. Es útil en los casos en los que solo queremos implementar el rasgo en algún tipo pero no tenemos datos.
¿Cómo definir una estructura?
Una estructura se define mediante la palabra clave struct seguida de los elementos del par de claves.
Rust
// typical c struct struct Student{ name:String, roll: u64, dept: String, } // A unit struct struct Unit; // A tuple struct struct Pair(i32, f32);
Aquí hemos definido una estructura de Estudiante utilizando la palabra clave struct y sus elementos: «nombre», «rollo» y «depto», junto con sus tipos de datos esperados. También hemos definido la estructura unitaria y la estructura tupla. Cuando definimos la estructura, no se le asigna memoria. Solo cuando lo inicialicemos, se asignará.
Ahora, inicializaremos nuestra estructura Student. Se accede a los elementos de la estructura usando el «.» (punto) operador.
Rust
#[derive(Debug)] struct Student{ name:String, roll: u64, dept: String, } fn main() { let student1 = Student{ name: String::from("Prem"), roll: 50, dept:String::from("CSE"), }; println!("{:?}",student1.name); }
Producción:
"Prem"
Actualización de valores de una estructura definida
Dado que queremos actualizar el valor de una estructura, la variable por la que la estamos inicializando, es decir, estudiante1 en el caso anterior, debe declararse mut (una variable que se puede actualizar), de lo contrario, por defecto es inmutable (no se puede actualizar ).
Rust
#[derive(Debug)] struct Student{ name:String, roll: u64, dept: String, } fn main() { let mut student1 = Student{ name: String::from("Prem"), roll: 50, dept:String::from("CSE"), }; student1.roll=60; println!("{:?}",student1.roll); }
Producción:
60
Estructura anidada
Como se dijo anteriormente, podemos usar una estructura dentro de otra estructura. Dejanos ver.
Rust
#[derive(Debug)] struct Addr{ loc:String, pin:u64, } struct Student{ name:String, roll: u64, dept: String, addr: Addr, } fn main() { let add1=Addr{ loc: String::from("world"), pin:700001, }; let student1 = Student{ name: String::from("Prem"), roll: 50, dept:String::from("CSE"), addr:add1, }; println!("{:?}",student1.addr.pin); }
Producción:
700001
Aquí tratamos de agregar una estructura de direcciones a la estructura de los estudiantes. Una cosa a tener en cuenta es que la estructura addr debe definirse antes que la estructura del estudiante y lo mismo ocurre durante la inicialización. Observe el método utilizado para acceder a los elementos de una estructura que forma parte de otra estructura. Para esto, hemos usado el operador punto dos veces como en student1.addr.pin.
Definición de métodos para una estructura
Rust
#[derive(Debug)] struct Triangle { base: f64, height: f64, } impl Triangle { fn area(&self) -> f64 { self.base * self.height * 0.5 } } fn main() { let tri1 = Triangle { base: 3.0, height: 5.0, }; println!("The area of the triangle is = {}",tri1.area()); }
Producción:
The area of the triangle is = 7.5
Comenzamos un bloque impl (implementación), dentro del cual definimos el área de método para el triángulo. Pasamos la dirección de la instancia de la estructura a la función y usamos self para referirnos a ella.