Comenzando con Rust (III)

Etiquetas

Contenido anterior

En la entrada anterior vimos cómo crear variables inmutables y mutables (let y let mut) .

Ahora vamos a estudiar las cosntantes que van a darnos alguna ventajilla sobre todo si lo que quieres es un valor global (sea visto por todo el código) que no cambie nunca.

Crear una constante es algo tan sencillo como lo siguiente:

const MENSAJE:&str = "Soy PEREDAFP";
fn main() {
println!("Hola Mundo {}", MENSAJE);
}

En entradas siguientes veremos que es esto de &str, para lo que vamos a tratar aquí nos basta saber que es la forma de crear una cadena.

En las constantes es necesario indicar el tipo siempre. Si queremos crear una constante llamada AUMENTO que contenga un 1: const AUMENTO: i32 = 1;

Si el nombre de la constante no está formado todo por letras mayúsculas el compilador mostrará un aviso:

const mensaje:&str = "Soy PEREDAFP";
  |       ^^^^^^^ help: convert the identifier to upper case: `MENSAJE`

Volveremos a hablar de const al tratar punteros y una cosa muy curiosa de concurrencia.

Habrás observado que todo programa de Rust contiene la palabra clave fn seguido de paréntesis (para definición de una función un poco más adelante) y el código está envuelto por {}.

Cada bloque de código que es separado del resto por {} es un ámbito distinto. En un ámbito únicamente se pueden utilizar las variables creadas en él y las creadas en ámbitos superiores.

Por ejemplo ámbito con variable de ámbito superior podrás comprobar que variable1 es accesible tanto dentro como fuera de las llaves. Sin embargo este código no compila e indica que variable1, en la línea7, no está definida en ese ámbito (scope), claro la hemos creado al entrar en las llaves y al salir de ellas Rust la ha eliminado y es imposible acceder a una variable que no existe.

¿Y a qué viene todo esto? si recuerdas en el artículo anterior hablamos de que CASI todas las líneas de un programa Rust deben terminar con ; y también dijimos que las que no terminan con ; son las más interesantes (bueno, esto era para darle un poco de emoción al asunto).

También habrás leído que Rust es un lenguaje basado en expresiones. Pero ¿Qué es una expresión? una expresión devuelve un valor. Si una línea, o líneas, de código no devuelve un valor se denomina sentencia. Cuando utilizas let para crear una variable no se devuelve ningún valor (sentencia), pero la parte de la derecha del igual sí debe devolver un valor que será asignado a dicha variable. En este ejemplo puedes ver la diferencia entre sentencia y expresión. Prueba a cambiar la línea 3 por let variable2 = let variable3 = 2; y lee los comentarios que muestra el compilador.

Claro, let variable3 = 2 no devuelve ningún valor ya que es una sentencia y el let de más a la izquierda está esperando un valor que poder asignar a su variable2 del alma.

Una de las cosas más interesantes que tiene Rust es que cualquier expresión puede ser una sentencia si termina con ; y puede ser una expresión pura y dura si no termina en ; Ahora igual no le ves mucho el sentido, pero cuando veamos el tema funciones comprenderás la importancia de todo esto.

Vamos a estudiar estos dos códigos:

Son prácticamente iguales. Si en código 2 te olvidas del» :?» que aparece entre los {} y del ; en el que termina la línea 4 son el mismo código.

Pero el primero muestra un 2 en pantalla y el segundo () ¿Por qué? Porque el primero en la línea 4 , y antes de salir del ámbito que hemos creado con las {},termina con una expresión variable1 + 1 (observa que no tiene punto y coma) y por tanto devuelve el valor, en este caso, 2 y el segundo termina en variable1 + 1;(termina con punto y coma) y por tanto es una sentencia. Los bloques son expresiones y si terminan con una línea sin ; devuelve un valor y en caso contrario devuelve () que no es otra cosa que una tupla vacía (el término tupla lo estudiaremos un poco màs adelante)

Como ejercicio de este artículo vamos a jugar un poco con este código obtenido de rust by example. Nuestro trabajo va a consistir en quitar y poner ; en las líneas 10 y 15. Explicaremos a continuación el resultado en cada caso

Hasta la siguiente.

Comenzando con Rust (II)

Etiquetas

Entrada Anterior Comenzando con Rust(I)

En esta entrada vamos a comenzar con Rust para darnos de bruces con algunas de las cosas que más curiosas me parecieron a mí, programador que llevaba tiempo con Python, al comenzar.

Accede a este enlace de Playground de Rust. Puedes ejecutar el programa pulsando en RUN. Siéntete libre de modificar lo que quieras, es tu código.

Si vienes de programar en Python ves las cosas algo raras pero no demasiado raras. No creo que tengas problema si te digo que modifiques el programa para que muestre «Estoy empezando con Rust».

Sencillo, cambio «Hola Mundo» por «Estoy empezando con Rust». Lo ejecuto y ya.

Como, a diferencia de Python, Rust no es un lenguaje interpretado verás que en la salida que se muestra en el trozo de pantalla de salida aparece:

Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 2.82s
     Running `target/debug/playground`

Todos los programas escritos en Rust deben pasar un paso previo antes de poder ser ejecutados: la compilación. En el caso de Rust este programa es rustc que veremos con más detalle en otra entrada. La ventaja que tiene la compilación es que, una vez generado el programa ejecutable ya no necesitarías más a Rust. Bastaría con copiar el fichero ejecutable creado, copiarlo en otra máquina (eso sí, con el mismo sistema operativo que en la que has generado el código. Para virguerías de compilaciones para otros sistemas operativos y procesadores diferentes a los de tu máquina siga, siga, siga…) y ya.

El compilador de Rust es muy tiquismiquis, pero da mucha información de por qué no deja seguir. Prueba ahora a ejecutar esto

  Compiling playground v0.0.1 (/playground)
error: expected `;`, found `println`
 --> src/main.rs:2:18
  |
2 |     let i:u32 = 7
  |                  ^ help: add `;` here
3 |     println!("Estoy empezando con Rust");
  |     ------- unexpected token

Observa como te da la ayuda: en la línea 2 añade un ;

Ha sido fácil. Pero no te lleves la impresión de que todas las líneas en un programa Rust deben terminar con ;, de hecho, las líneas más interesantes son las que no lo tienen, pero sigamos con calma que nos liamos.

En este segundo programa hemos añadido una cosa que igual te sorprende. Bueno, una no, dos. La primera es let, palabra reservada del lenguaje que indica que se va a crear una variable. Fácil.

La segunda es el :u32, ¡uf! si no has visto nada antes de tipos te vas a encontrar perdido. Te recomiendo que pares y estudies el capítulo 3, apartado 2 del libro de Rust. Ya advertí que no iba a ser sencillo.

En Python puedes hacer cosas como esta:

i = 7
i = 34
print(i)

Si intentas algo similar en Rust, algo como esto, el compilador se para y muestra un mensaje:

 |
2 |     let i = 7;
  |         -
  |         |
  |         first assignment to `i`
  |         help: consider making this binding mutable: `mut i`
3 |     i = 12;
  |     ^^^^^^ cannot assign twice to immutable variable

En la ayuda nos dice que consideremos hacer «mutable» a i. Y ¿Cómo se hace eso? el código anterior debes modificarlo para que sea igual a este

Con mut le estamos diciendo al compilador que esa variable podrá ser modificada después de ser creada. De hecho, si hacemos que una variable sea mut y no cambiamos su valor a lo largo del programa el compilador nos avisa (aviso de variable mut sin cambios) aunque ejecuta, la cosa no es tan grave. ¿ O sí?. Tú decides.

|
2 |     let mut i = 7;
  |         ----^
  |         |
  |         help: remove this `mut`
  |
  = note: `#[warn(unused_mut)]` on by default

En algunos programas de Rust puedes encontrarte cosas como las que mostramos aquí Esto nos va a permitir la variable i como i32 y, después de volverle a asignar un valor con let, como cadena de caracteres. El término utilizado para definir este fenómeno es shadowing. Vamos, lo mismo que haces en Python con:

i = 7
print(i)
i="hola"
print(i)

Pero dejas claro que sabes que eso es así, no que utilizas a lo tonto un nombre de variable que, curiosamente, ya habías utilizado antes con un tipo diferente. ¿No te ha pasado nunca?

De momento no escribo más. Te dejo algunos ejercicios para que asientes conocimientos:

Ejercicio 1: ¿Por qué este programa no compila? Ejercicio 1

Ejercicio 2: ¿Y por qué este sí? Ejercicio 2

Ejercicio 3: ¿Por qué este programa muestra en pantalla 255 en vez de 256?¿Qué ocurre si eliminas el saturating_add(1)? Busca información sobre saturating_add y similares Ejercicio 3

Un saludo

Comenzando con Rust ( I )

Etiquetas

Comienzo con este el primero de una serie, espero que larga, de artículos sobre el lenguaje de programación Rust.

No soy un experto en este lenguaje y el planteamiento de estas entradas en el blog son más bien una reflexión en voz alta que verdades absolutas y contrastadas.

Me planteo como retos los siguientes:

  • Utilizar única y exclusivamente la librería estándar de este lenguaje.
  • No utilizar Cargo hasta que queden asentados la mayor parte de los conceptos que me gustaría tratar.
  • Después de obtener un dominio medio-alto de la concurrencia con Rust, realizar un servidor de algún protocolo interesante como MQTT ( de aquí surge la idea: https://taller-1-fiuba-rust.github.io/proyecto_2C2021.html),un bot de Telegram (intentar crear la librería de conexión a la API desde cero…bufff pero un reto es un reto) o algún proyecto barebone ( sobre la raspberry Pi Zero o similar)

Temas como asincronía y webassembly me parecen interesantes pero los dejo para más adelante.

El camino va a ser largo y creo que duro. Para empezar veo muy necesario conocer los intríngulis de los sistemas informáticos y para ello nada mejor que realizar este curso de Juan Gozález sobre el ensamblador de RISC-V https://github.com/myTeachingURJC/2019-20-LAB-AO/wiki Los conceptos de Pila (stack) y montón (heap) Juan los explica que no deja dudas (excepcional también lo claro que queda recursividad. Es un grande) y son fundamentales para entender propiedad y préstamo, una de las características de Rust que más complican la vida pero que hace que el código generado no sufra de errores que son mucho más difíciles de detectar y corregir cuando el programa ya se está ejecutando.

Si es la primera vez que te enfrentas a Rust no te recomiendo que instales nada en tu máquina y sí que utilices https://play.rust-lang.org/

Si termina picándote el gusanillo obviamente tendrás que instalarlo y para eso: https://www.rust-lang.org/tools/install

Libros que recomiendo:

  • Otro libro que me ha gustado mucho es Programming Rust, Segunda Edición de Jim Blandy, Jason Orendorff, Leonora F. S. Tindall
  • Para entender los diferentes tipos de punteros (tranquilo, ya llegaremos a ellos) el libro de Tim McNamara Rust in Action

Si de concurrencia estás pez y quieres asentar o adquirir conocimientos, el libro de Ricardo Galli es excelente: https://github.com/gallir/principios_algoritmos_concurrencia/tree/master Tampoco habla de Rust pero va a dejarte bastante claros los principios en los que se basa este follón que es la concurrencia. Habla de canales en golang pero pueden servirte de mucha ayuda para comprenderlos en Rust (después de leer este libro, y estés haciendo cosicas concurrentes, pásate por el capítulo 19 de Programming Rust)

Tengo pendiente Rust For Rustaceans Idiomatic Programming for Experienced Developers by Jon Gjengset Rust For Rustaceans Idiomatic Programming for Experienced Developers by Jon Gjengse

Tanto Tim McNamara como Jon Gjengse tienen canal de youtube en el que dan masterclass sobre temas Rust.

Solo le he echado un vistazo pero parece divertido: https://sokoban.iolivia.me/ Realización de un videojuego 2D con Rust

En español he visto pocos recursos. Destacaría dos:

Como gestionar los comentarios suele ser bastante rollo, si queréis enviarme información sobre Rust, criticar de manera positiva las cosas que vaya publicando o indicarme en qué me he equivocado, podéis contactar conmigo a través de mi cuenta de twitter: @PeredaFP. Intentaré hacer una selección de las cosas más interesantes para que sean publicadas en siguientes entradas.

Un saludo

Estudiamos una hoja de cálculo

Descarga esta hoja de cálculo: CONTROLCARRERA

Y realiza la siguiente actividad:

1.- Describe brevemente para qué sirve esta hoja de cálculo

2.- ¿Cuántas hojas contiene? ¿para qué sirve cada una?

3.- En la celda Dorsales.B4 aparece una fórmula con los textos “ninguno” y “dorsales dulicados” crea una celda en la hoja de Configuración para cada uno de estos textos y modifica dicha fórmula

4.- ¿Cómo se obtiene el total de dorsales que aparece en la celda Dorsales.C4?

5.- ¿Qué ocurre si duplicas un dorsal? Describe el procedimiento realizado

6.- ¿Cómo se obtiene la edad del corredor?

7.- Observa que para obtener el sexo del corredor se muestran los valores M y F ¿Cómo podrías cambiar las letras que identifican a dicho sexo? ¿ocurre algo si las cambias? ¿por qué?

8.-Estudia cómo se obtiene la categoría del corredor.

9.- Modifica la hoja para que solo haya categoría SUB20 y SUB40 tanto para hombres como para mujeres.

10.- ¿Cómo se obtiene el puesto en la categoría?Pista: la columna A guarda algún secreto

11.- Describe cómo se obtienen el nombre, apellidos y categoría del corredor al añadir el dorsal en la hoja de Resultados

12.- En la hoja “Cuadro de Honor” aparecen, en alguna de las clasificaciones un #N/D. Soluciónalo

13.- ¿Cómo se obtiene el corredor más veterano?

14.- Estudia y modifica el cuadro de honor para que únicamente contenga las categorías que has creado en el punto 9

15.- Si se te ocurre alguna mejora…ADELANTE

Os recuerdo que la fecha de examen es el 16 de noviembre, la entrega del trabajo del control de notas es el día 15 de noviembre y debéis añadir este ejercicio a entregar en la misma fecha que el control de notas, o sea, el 15 de noviembre

Un saludo