Daniel García Moreno (@danigm)
<danigm@gnome.org>
https://danigm.net
Rust es un lenguaje de programación de sistemas extremadamente rápido, previene fallas de segmentación y garantiza la seguridad de los hilos de ejecución.
// hola.rs
fn main() {
println!("Hola Mundo!");
}
rustc hola.rs
./hola
Hola Mundo!
Recolector de basura, no son eficientes
curl https://sh.rustup.rs -sSf | sh
export PATH=$PATH:$HOME/.cargo/bin
Además se pueden instalar otros targets para compilación cruzada
rustup target list
rustup target install x86_64-pc-windows-gnu
cargo new --bin hola
# cat Cargo.toml
[package]
name = "hola"
version = "0.1.0"
authors = ["Daniel García Moreno "]
[dependencies]
// cat src/main.rs
fn main() {
println!("Hello, world!");
}
cargo run
Hello, world!
cargo build --release
cargo check
cargo test
cargo doc
cargo search time
cargo add package
cargo install package
cargo publish
extern crate chrono;
use chrono::prelude::*;
fn get_time() -> DateTime {
let d = Local::now();
d
}
/// función que suma los números de 0 a n
fn get_sum(n: i32) -> i32 {
let mut x: i32 = 0;
for i in 0..n {
x += i;
}
x
}
fn dup(txt1: &str, txt2: &str) {
println!("{0} {1} {0} {1}", txt1, txt2);
}
// función principal
fn main() {
let t = get_time();
println!("Hola Mundo! {}", t);
let i = get_sum(10);
println!("Resultado: {}", i);
dup("esto", "otro");
}
pub struct Persona {
nombre: String,
apellido1: String,
apellido2: Option,
edad: i32,
prof: Profesion,
}
impl Persona {
pub fn new(nombre: String, apellidos: (String, String)) -> Persona {
Persona {
nombre: nombre,
apellido1: apellidos.0,
apellido2: Some(apellidos.1),
edad: 0,
prof: Profesion::Docotor(Profesion::Medicina),
}
}
}
enum Profesion {
Informatica,
Medicina,
Doctor(Profesion),
Estudiante(Profesion),
Otro(String),
}
let v = vec![1, 2, 3];
let v2 = v;
let a = v[0]; // Error, intentamos usar v después de moverlo
let mut v = vec![1, 2, 3];
let v2 = &v; // referencia
let v3 = &v; // referencia
let a = v[0];
// Error, como hay referencias de lectura, no puede existir una referencia mutable
let v4 = &mut v;
let mut n = 3;
{
let nref = &n;
*nref = 5;
}
println!("n: {}", n);
fn eliminar_prefijo<'a, 'b>(orig: &'a str,
prefijo: &'b str)
-> &'a str {
&orig[prefijo.len()..]
}
fn main() {
let x;
{
let a = "texto:hola".to_string();
let b = "texto:";
x = eliminar_prefijo(&a, &b);
}
println!("X: {}", x);
}
fn division(n: i32, d: i32) -> Result<i32, &str> {
if d == 0 {
return "No se puede dividir por cero";
}
n / d
}
fn propagando() -> Result<i32, &str> {
let n = division(3, 0)?;
println!("resultado de la división: {}", n);
n
}
fn main() {
let r = propagando();
if r.is_ok() {
// accediendo al valor, si no es ok, fallará
println!("valor: {}", r.unwrap());
}
assert_eq!(r, Err("No se puede dividir por cero"));
}
let mut n: Option<i32> = None;
// Error porque es un option, no un i32
let suma = n + 3;
if n.is_some() {
let suma = n.unwrap() + 3;
}
n = Some(5);
let suma = match n {
Some(i) => i + 3,
None => 0,
};
match n {
i if i < 0 => {
println!("número negativo: {}", i);
},
5 => println!("n es 5"),
_ => println!("cualquier cosa"),
};
if let Some(n) = funcion_devuelve_option(23) {
println!("{}", n + 4);
}
if let Err(error) = funcion_result(3, 5) {
println!("ha ocurrido un error");
return;
}
let n1 = match n {
i if i > 0 => -i,
0 => 0,
_ => 42,
};
trait Operaciones : PartialEq {
fn area(&self) -> f64;
fn perimetro(&self) -> f64;
fn print(&self) {
println!("Area: {}", self.area());
println!("Perímetro: {}", self.perimetro());
}
}
use std::f64::consts::PI;
#[derive(Debug, PartialEq)]
struct Circulo {
centro: (i32, i32),
radio: i32,
}
impl Operaciones for Circulo {
fn area(&self) -> f64 { PI * self.radio.pow(2) as f64 }
fn perimetro(&self) -> f64 { use std::f64::consts::PI; PI * self.radio as f64 * 2.0 }
}
let c = Circulo { centro: (0, 0), radio: 5 };
c.print();
#[derive(Debug)]
struct Rectangulo {
alto: i32,
largo: i32
}
impl PartialEq for Rectangulo {
fn eq(&self, other: &Rectangulo) -> bool {
self.alto * self.largo == other.alto * other.largo
}
}
impl Operaciones for Rectangulo {
fn area(&self) -> f64 {
(self.alto * self.largo) as f64
}
fn perimetro(&self) -> f64 {
(self.alto * 2 + self.largo * 2) as f64
}
fn print(&self) {
println!(" * Area : {} m2", self.area());
println!(" * Perímetro: {} m", self.perimetro());
}
}
let r = Rectangulo {
alto: 10,
largo: 5,
};
r.print();
macro_rules! cat {
( $( $x:expr ),* ) => {{
let mut base = String::new();
$(
base = base + &format!("-{}", $x);
)*
base[..]
}}
}
println!("CAT: {}", cat!("hola", "adios", "123"));
macro_rules! foo {
(x => $e:expr) => (println!("mode X: {}", $e));
(y => $e:expr) => (println!("mode Y: {}", $e));
}
foo!(y => 3);
/// Constructs a new `Rc<T>`.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// ```
pub fn new(value: T) -> Rc<T> {
// Implementation goes here.
}
pub fn add_two(a: i32) -> i32 { a + 2 }
#[cfg(test)]
mod tests {
use super::add_two;
#[test]
fn it_works() {
assert_eq!(4, add_two(2));
}
}
/// This function adds two to its argument.
///
/// # Examples
///
/// ```
/// use adder::add_two;
///
/// assert_eq!(4, add_two(2));
/// ```
pub fn add_two(a: i32) -> i32 { a + 2 }