Lenguaje de programación Rust: Guía para principiantes

Compartir esta publicación

En nuestro lugar de trabajo, asumimos el reto como desarrolladores front-end de adentrarnos en Rust y explorar cómo podemos crear aplicaciones web. El paso inicial fue familiarizarnos con los fundamentos del lenguaje estudiando la documentación. Al iniciar mi estudio de Rust, reconocí similitudes entre Rust y JS/TS, dibujarlas era importante para mí para facilitar una comprensión más intuitiva. Quise compartir mi camino de aprendizaje, escribiendo este artículo que esboza mi exploración de Rust desde la perspectiva de un desarrollador front-end.

El lenguaje de programación Rust fue desarrollado originalmente por Mozilla para Firefox, y también se utiliza en grandes empresas como Facebook, Apple, Amazon, Microsoft y Google. Proyectos notables como Dropbox, npm, GitHub y Deno también aprovechan Rust. También el compilador de Next.js «Turbopack» ha contribuido a un notable aumento del 94,7% de la velocidad en la versión 14 de Next.js.

La razón por la que el lenguaje de programación Rust está ganando popularidad puede atribuirse a varios factores clave. En primer lugar, Rust es un lenguaje compilado que genera código máquina eficiente. Esta característica garantiza que las aplicaciones desarrolladas con Rust ofrezcan un rendimiento excepcional. Además, el lenguage de programación Rust es muy fiable gracias a su compilador, que evita eficazmente comportamientos indefinidos que, de otro modo, podrían provocar resultados inesperados o fallos.

Otra es su eficiencia de memoria. Mientras que muchos lenguajes gestionan la memoria automáticamente, como el recolector de basura de JavaScript, o tienen un control total sobre la gestión de la memoria, como en C o C++, Rust introduce un enfoque único llamado modelo de propiedad. (Volveremos sobre este tema más adelante)

En las próximas secciones de este artículo, exploraremos temas esenciales del lenguaje de programación Rust desde la perspectiva de un desarrollador front-end. Estos temas incluyen tipos de datos, variables, mutabilidad, funciones, tuplas, arrays y structs, así como referencias y préstamos.

Lenguaje de programación Rust

Tipos de datos

El contraste entre JavaScript y el lenguaje de programación Rust se manifiesta principalmente en su enfoque de los tipos de datos. JavaScript adopta un sistema de tipado dinámico, mientras que Rust emplea tipado estático. En Rust, es obligatorio determinar los tipos de todas las variables en tiempo de compilación, una característica que se asemeja más a TypeScript.

Cada valor en Rust está asociado a un tipo de datos específico, y estos tipos se clasifican en dos grupos principales: Tipos escalares y tipos compuestos. En contraste, JS/TS tiene un pequeño conjunto de tipos de datos como números, cadenas, booleanos y objetos. Los tipos escalares en Rust incluyen enteros (con y sin signo), números en coma flotante, booleanos y caracteres, mientras que los tipos compuestos comprenden tuplas y matrices.

  Entrevista con Ileana Diaz - Desarrolladora de Backend en Apiumhub

Enteros

Una distinción notable en los tipos de datos es que, a diferencia de JS/TS, Rust proporciona opciones de tamaño específico para enteros y números de punto flotante. Esto permite regular con precisión la cantidad de memoria asignada a cada tipo. En consecuencia, Rust destaca por su eficiencia de memoria y su alto rendimiento.

Rust

Números flotantes

Rust ofrece dos tipos de coma flotante: f32 y f64, con tamaños de 32 bits y 64 bits. El tipo por defecto es f64, porque proporciona una velocidad similar a f32 ofreciendo más precisión. Es importante tener en cuenta que todos los tipos de coma flotante en Rust tienen signo.

let x = 5.8;

Booleanos

En Rust como en JS/TS, el tipo booleano tiene dos valores potenciales: true y false. Tienen un tamaño de un byte, y se denota por bool.

let isRustReliable = true;
let isRustReliable: bool = true;

Personajes

El tipo char de Rust tiene un tamaño de cuatro bytes. Representa específicamente un valor escalar Unicode, lo que le permite abarcar una gama más amplia de caracteres más allá de ASCII. Esto incluye letras acentuadas, diferentes caracteres del alfabeto, emojis y espacios de ancho cero, haciendo que el tipo char de Rust sea más versátil en el manejo de diversos conjuntos de caracteres.

let char_type = 'a'
let char_type: char = 'A';

Tuplas

Una tupla agrupa varios tipos en un tipo compuesto. Las tuplas tienen una longitud predeterminada y, una vez declaradas, no se pueden ampliar ni eliminar.

let origin: (i8, u8, f64) = (-5, 2, 2.2)
let (a,b,c) = origin; // destructuring in tuple
let firstElement = origin.0; // indexing

Matrices

Los arrays, a diferencia de las tuplas, requieren que cada uno de sus elementos comparta el mismo tipo. A diferencia de los arrays en JS/TS, los arrays en Rust tienen una longitud fija, lo que hace imposible añadir o eliminar elementos directamente. Si se necesita un redimensionamiento dinámico, similar a los arrays en JS/TS, los vectores en Rust serían probablemente la alternativa adecuada.

let origin: [i8, 3] = [1, 2, 3];
let origin = [4; 3] // means [4,4,4]
let first = origin[0];

Variables y mutabilidad

En Rust, el comportamiento por defecto de las variables es la inmutabilidad, lo que significa que sus valores no pueden ser cambiados una vez asignados. La palabra clave let se usa para declarar variables, y si quieres una variable mutable, necesitas usar explícitamente mut después de let.

// Immutable variable
let x = 5;
// Mutable variable
let mut y = 10;
y = 15; // Valid because y is mutable

También hay constantes y una distinción notable entre let es que no se puede usar mut con constantes. Las constantes, a diferencia de las variables, son inherentemente inmutables. Se declaran utilizando la palabra clave const, y su tipo debe estar explícitamente anotado.

const MULTIPLIER: u32 = 5;

Las constantes pueden declararse en cualquier ámbito, incluido el global, lo que las hace valiosas para valores compartidos en distintas partes del código.

  Katas de código; una manera de convertirse en un mejor desarrollador de software

Funciones

En el lenguaje de programación Rust, los cuerpos de las funciones consisten en una serie de sentencias y opcionalmente terminan en una expresión. Las sentencias son instrucciones que realizan acciones pero no devuelven un valor, mientras que las expresiones evalúan a un valor resultante.

fn main() {
    let y = {
        let x = 3; // statement
        x + 1 // expression which evaluates the value assigned to y
    };


    println!("The value of y is: {y}");
}

En JavaScript, puedes crear funciones utilizando declaraciones de función o expresiones. En Rust, puedes usar declaraciones de funciones o funciones lambda, conocidas como cierres, cada una con su propia sintaxis y características distintivas.

JS

// Function Declaration
function add(a, b) {
  return a + b;
}

// Function Expression
const subtract = function(a, b) {
  return a - b;
};

Rust

// Function Declaration
fn add(a: i32, b: i32) -> i32 {
    a + b
}

// Closure (Lambda Function)
let subtract = |a: i32, b: i32| -> i32 {
    a - b
};

Propiedad, referencias y préstamos

La propiedad es un concepto fundamental en el lenguaje de programación Rust que establece un conjunto de reglas que rigen la forma en que el lenguaje gestiona la memoria a lo largo de la ejecución del programa. En JavaScript, la gestión de la memoria suele correr a cargo de un recolector de basura, que recupera automáticamente la memoria que ya no se utiliza, liberando a los desarrolladores de responsabilidades explícitas de gestión de la memoria. A diferencia de Rust, la abstracción de JavaScript de los detalles de la memoria lo hace adecuado para el desarrollo de alto nivel, pero sacrifica el control detallado sobre la asignación y desasignación de memoria.

La pila, organizada como una estructura de tamaño fijo FIFO (primero en entrar, primero en salir), contrasta con el montón, un espacio de memoria sin límites y menos organizado con un tamaño desconocido en tiempo de compilación. El asignador de memoria de Rust localiza dinámicamente un espacio disponible en el montón, lo designa como en uso y devuelve un puntero que representa la dirección de esa ubicación.

  Liquibase en Kubernetes

Las reglas de propiedad clave en Rust incluyen que cada valor sólo puede tener un propietario, el valor se elimina de la memoria cuando el propietario sale del ámbito, y sólo puede haber un propietario en un momento dado.

En Rust, la gestión automática de la memoria se ve facilitada por la función drop, que se llama cuando una variable sale del ámbito.

rust
{
 // `s` is not valid here; it’s not yet declared
 let s = "hello"; // `s` is valid from this point forward


 // do stuff with `s`
} // this scope is now over, and `s` is no longer valid
                 // this scope is now over, and s is no longer valid

Rust utiliza referencias, denotadas por el símbolo &, que permiten referirse a un valor sin tomar posesión de él. Las referencias garantizan que los datos a los que apuntan siguen siendo válidos durante el tiempo de vida de la referencia.

let original = String::from("hello");
let reference = &original; // 

Las referencias de Rust son inmutables por defecto, lo que significa que no pueden modificar los datos a los que apuntan. Sin embargo, las referencias mutables, denotadas por &mut, permiten modificaciones a los datos referenciados.

let mut value = 42;
let reference = &mut value; // Mutable reference to `value`


// Modify `value` through the mutable reference
*reference = 10;

Una restricción importante de las referencias mutables es que, si tienes una, no puedes tener ninguna otra referencia -mutable o inmutable- al mismo valor.

let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s; // ERROR: Cannot have multiple mutable references to `s`

Esta restricción evita las carreras de datos en tiempo de compilación. Las carreras de datos se producen cuando varios punteros acceden simultáneamente a los mismos datos, al menos uno de ellos los modifica y no existe ningún mecanismo de sincronización.

// In Rust, you cannot mix mutable and immutable references.
let s = String::from("hello");
let r1 = &s;    // No problem
let r2 = &s;    // No problem
let r3 = &mut s; // BIG PROBLEM: Cannot have a mutable reference alongside immutable references

El lenguaje de programación Rust impone la regla de que se puede tener una referencia mutable o cualquier número de referencias inmutables a un valor – este es el principio de referencias mutable exclusivas o inmutables compartidas.

CTA Software

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Suscríbete a nuestro boletín de noticias

Recibe actualizaciones de los últimos descubrimientos tecnológicos

¿Tienes un proyecto desafiante?

Podemos trabajar juntos

apiumhub software development projects barcelona
Secured By miniOrange