jueves, 6 de julio de 2023

Rust: Variables


Rust proporciona seguridad de tipos a través de tipos estáticos. Los enlaces de variables son inmutables de forma predeterminada:

fn main() {

    let x: i32 = 10;

    println!("x: {x}");

    // x = 20;

    // println!("x: {x}");

}


Rust verá cómo se usa la variable para determinar el tipo:


fn takes_u32(x: u32) {

    println!("u32: {x}");

}


fn takes_i8(y: i8) {

    println!("i8: {y}");

}


fn main() {

    let x = 10;

    let y = 20;


    takes_u32(x);

    takes_i8(y);

    // takes_u32(y);

}


cargo run

   Compiling hello_cargo v0.1.0 

    Finished dev [unoptimized + debuginfo] target(s) in 0.30s

     Running `target/debug/hello_cargo`

u32: 10

i8: 20


Pero eso no significa que se descuide el tipado estatico, si corremos el programa anterior descomentando la linea "    // takes_u32(y); " obtendremos: 

$ cargo run

   Compiling hello_cargo v0.1.0 

error[E0308]: mismatched types

  --> src/main.rs:15:15

   |

15 |     takes_u32(y);

   |     --------- ^ expected `u32`, found `i8`

   |     |

   |     arguments to this function are incorrect

   |

note: function defined here

  --> src/main.rs:1:4

   |

1  | fn takes_u32(x: u32) {

   |    ^^^^^^^^^ ------

help: you can convert an `i8` to a `u32` and panic if the converted value doesn't fit

   |

15 |     takes_u32(y.try_into().unwrap());

   |                ++++++++++++++++++++


For more information about this error, try `rustc --explain E0308`.

error: could not compile `hello_cargo` due to previous error


Es muy importante enfatizar que las variables declaradas así no son de algún tipo de dinámica "cualquier tipo" que pueda contener cualquier dato. El código máquina generado por tal declaración es idéntico a la declaración explícita de un tipo. El compilador hace el trabajo por nosotros y nos ayuda a escribir código más conciso.


El siguiente código le dice al compilador que copie en un determinado contenedor genérico sin que el código especifique explícitamente el tipo contenido, usando _ como marcador de posición:

fn main() {

    let mut v = Vec::new();

    v.push((10, false));

    v.push((20, true));

    println!("v: {v:?}");


    let vv = v.iter().collect::<std::collections::HashSet<_>>();

    println!("vv: {vv:?}");

}


collect se basa en FromIterator, que implementa HashSet.

No hay comentarios.:

Publicar un comentario