Búsqueda de sitios web

Serie de conceptos básicos de Rust n.° 4: matrices y tuplas en Rust


En el cuarto capítulo de la serie Rust, aprenderá sobre los tipos de datos compuestos, matrices y tuplas.

En la publicación anterior, aprendiste sobre los tipos de datos escalares en Rust. Son números enteros, coma flotante, caracteres y booleanos.

En este artículo, veremos los tipos de datos compuestos en el lenguaje de programación Rust.

¿Qué es el tipo de datos compuestos en Rust?

Los tipos de datos compuestos pueden almacenar múltiples valores en una variable. Estos valores pueden ser del mismo tipo de datos escalares o de diferentes tipos escalares.

El lenguaje de programación Rust tiene dos tipos de datos:

  • Arrays: almacena múltiples valores del mismo tipo.

  • Tuplas: Almacena múltiples valores, ya sean del mismo tipo o incluso de diferentes tipos.

¡Así que veámoslos!

Matrices en Rust

Los arreglos en el lenguaje de programación Rust tienen las siguientes propiedades:

  • Cada elemento debe ser del mismo tipo.

  • Las matrices tienen una longitud fija.

  • Las matrices se almacenan en la pila, es decir, se puede acceder a los datos almacenados en ella rápidamente

La sintaxis para crear una matriz es la siguiente:

// without type annotation
let variable_name = [element1, element2, ..., elementn];

// with type annotation
let variable_name: [data_type; array_length] = [element1, element2, ..., elementn];

Los elementos de una matriz se declaran entre corchetes. Para acceder a un elemento de una matriz, el índice al que se accederá se especifica entre corchetes.

Veamos un programa de ejemplo para entender esto mejor.

fn main() {
    // without type annotation
    let greeting = ['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'];

    // with type annotation
    let pi: [i32; 10] = [1, 4, 1, 5, 9, 2, 6, 5, 3, 5];

    for character in greeting {
        print!("{}", character);
    }

    println!("\nPi: 3.1{}{}{}{}", pi[0], pi[1], pi[2], pi[3]);
}

Aquí, defino una matriz de caracteres y otra matriz que almacena tipos i32 en ella. La matriz greeting tiene los caracteres de la cadena "¡Hola mundo!" almacenados en él como caracteres individuales. La matriz pi tiene los primeros 10 valores de Pi después de los valores decimales almacenados en ella como números individuales.

Luego imprimo cada carácter de la matriz greeting usando el bucle for. (Entraré en bucles muy pronto). Luego, imprimo los primeros 4 valores de la matriz pi.

Hello world!
Pi: 3.11415

Si desea crear una matriz donde cada elemento sea y y aparezca x un número de veces, puede hacerlo en Rust con el siguiente atajo:

let variable_name = [y; x];

Veamos una demostración...

fn main() {
    let a = [10; 5];

    for i in a {
        print!("{i} ");
    }
    println!("");
}

Creo una variable a que tendrá una longitud de 5. Cada elemento de esa matriz será '10'. Verifico esto imprimiendo cada elemento de la matriz usando el bucle for.

Tiene la siguiente salida:

10 10 10 10 10

Como ejercicio, intente crear una matriz de longitud x y acceda al elemento x+1st de la matriz. Mira qué pasa.

Tuplas en Rust

Una Tupla en el lenguaje de programación Rust tiene las siguientes propiedades:

  • Las tuplas, como las matrices, tienen una longitud fija.

  • Los elementos pueden ser del mismo o diferente tipo de datos escalares.

  • La tupla se almacena en la pila, es decir, un acceso más rápido.

La sintaxis para crear una tupla es la siguiente:

// without type annotation
let variable_name = (element1, element2, ..., element3);

// with type annotation
let variable_name: (data_type, ..., data_type) = (element1, element2, ..., element3);

Los elementos de una tupla se escriben dentro de los corchetes. Para acceder a un elemento se utiliza el operador punto y va seguido del índice de dicho elemento.

fn main() {
    let a = (38, 923.329, true);
    let b: (char, i32, f64, bool) = ('r', 43, 3.14, false);

    println!("a.0: {}, a.1: {}, a.2: {}", a.0, a.1, a.2);
    println!("b.0: {}, b.1: {}, b.2: {}, b.3: {}", b.0, b.1, b.2, b.3);

    // destructuring a tuple
    let pixel = (50, 0, 200);
    let (red, green, blue) = pixel;
    println!("red: {}, green: {}, blue: {}", red, green, blue);
}

En el código anterior, en las líneas 2 y 3 declaro dos tuplas. Estos solo contienen valores aleatorios que inventé en el momento. Pero mire de cerca, el tipo de datos de cada elemento en ambas tuplas es diferente. Luego, en las líneas 5 y 6, imprimo cada elemento de ambas tuplas.

En la línea 9, declaro una tupla llamada pixel que tiene 3 elementos. Cada elemento es la magnitud de los colores rojo, verde y azul para formar un píxel. Esto varía de 0 a 255. Entonces, idealmente, anotaría que el tipo sea (u8, u8, u8) pero esa optimización no es necesaria al aprender;)

Luego, en la línea 10, "desestructuro" cada valor de la tupla pixel y lo almaceno en variables individuales red, green y < código>azul. Luego, en lugar de imprimir los valores de la tupla pixel, imprimo los valores de red, green y blue variables.

Veamos el resultado...

a.0: 38, a.1: 923.329, a.2: true
b.0: r, b.1: 43, b.2: 3.14, b.3: false
red: 50, green: 0, blue: 200

Me parece bien :)

Bonificación: rebanadas

Estrictamente hablando, los sectores no son un tipo de datos compuestos en Rust. Más bien, una porción es... una porción de un tipo de datos compuesto existente.

Un sector consta de tres elementos:

  1. Un índice inicial

  2. El operador de sector (.. o ..=)

  3. Un índice final

A continuación se muestra un ejemplo del uso de una porción de una matriz.

fn main() {
    let my_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let my_slice = &my_array[0..4];

    for element in my_slice {
        println!("{element}");
    }
}

Al igual que C y C++, el signo comercial se utiliza para almacenar la referencia (en lugar de un puntero sin formato) de una variable. Entonces &my_array significa una referencia a la variable my_array.

Ahora, pasando al corte. El segmento se indica con [0..4]. Aquí, 0 es el índice de dónde comenzar el segmento. Y 4 es donde termina el segmento. El 4 aquí es un índice no inclusivo.

A continuación se muestra el resultado del programa para comprender mejor lo que está sucediendo:

0
1
2
3

Si desea un rango inclusivo, puede utilizar ..= como operador de división para un rango inclusivo.

fn main() {
    let my_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let my_slice = &my_array[0..=4];

    for element in my_slice {
        println!("{element}");
    }
}

Ahora, este rango va desde el elemento 0th hasta el elemento 4th y a continuación se muestra el resultado para demostrar que:

0
1
2
3
4

Conclusión

Este artículo sobre el lenguaje de programación Rust cubre los tipos de datos compuestos con cierta profundidad. Aprendió a declarar y acceder a valores almacenados en los tipos Array y Tuple. Además, observó el "tipo" de segmento y también cómo desestructurar una tupla.

En el siguiente capítulo, aprenderá sobre el uso de funciones en programas Rust.

Manténganse al tanto.