Skip to content

Instantly share code, notes, and snippets.

@gabrielhjs
Last active November 18, 2023 22:24
Show Gist options
  • Save gabrielhjs/dba5f360359700c37a7781b737f32c28 to your computer and use it in GitHub Desktop.
Save gabrielhjs/dba5f360359700c37a7781b737f32c28 to your computer and use it in GitHub Desktop.
Rust - Introdução

Rust

Índice

O que é?

Desenvolvida pela Mozilla Research em 2010, a Linguagem de Programação Rust vem ganhando força nos últimos anos, tendo sua versão estável lançada no ano de 2015.

Multiparadigma, foi desenvolvida com o intuito de ajudar os desenvolvedores na criação de aplicações mais seguras e mais rápidas, prevenindo falhas de segmentação. A linguagem de programação Rust é uma linguagem imperativa, funcional e orientada a objeto.

Características

  • Gerencia memória eficientemente sem runtime ou garbage collector;
  • Concorrência de disputa de dados;
  • Integra-se facilmente à outras linguagens;
  • Compilador amigável com mensagens de erro úteis;
  • Rápida para ser usada em aplicações de baixo nível;
  • Suporte inteligente para múltiplos editores;
  • Multiplataforma;
  • Possui uma alta confiabilidade;
  • Possui uma ótima documentação, entre outras.

Fonte: Treinaweb

Ecossistema

  • Rustc: Compilador
  • Rustup: Gerenciador de versão do rust
  • Cargo: Gerenciador de projetos e dependências
  • Rustfmt: Configuração de lint

Prós

  • Comunidade engajada;
  • Está em ascensão de uso;
  • Constante evolução;

Contras

  • Curva de aprendizado;
  • Linguagem verbosa;
  • Compilação lenta;

Variáveis

// Integers
let var: i8 = 1;
let var: i16 = 1;
let var: i32 = 1;
let var: i64 = 1;
let var: i128 = 1;
let var: isize = 1;

// Positive integers
let var: u8 = 1;
// ...
let var: usize = 1;

let var = 1u8;
let var = 23i32;

// Float
let var = 1.0; // f64
let var: f32 = 1.0;
let var = 1.0f32;

// char (stack)
let var = 'a';

// &str (stack)
let var = "My str";

// String (heap)
let var = String::from("My String");

// Array
let var: [i32; 2] = [0, 1];
let var = [1i64];

// Tuple
let var: (isize, &str) = (1, "str");
let var = (2, String::from("string")); // (i32, String)

// Vector
let var = Vec::from([1]); Vec<i32>
let var = vec![1]; // Vec<i32>

Mutabilidade

Por padrão todas as variáveis no rust são imutáveis. Para criar uma variável mutável é necessário adicional o prefixo mut. Ex:

let mut var = 2; // i32
var = 3;
let mut var = vec![1]; // Vec<i32>
var.push(2); // var: Vec<i32> = [1, 2]

Observação: Array e Tuple, mesmo que mutáveis, não podem ter ser tipo e tamanho alterados.

Funções

fn return_two() -> i32 {
  return 2;
}

fn return_two() -> i32 {
  2
}

fn receive_i32_and_print(var: i32) {
  println!("{var}");
}

fn receive_reference_and_print(var: &i32) {
  println!("{var}");
}

fn receive_mutable_i32_and_add_two(mut var: i32) {
  var += 2;
}

fn receive_mutable_reference_and_add_two(var: &mut i32) {
  *var += 2;
}

// Closure
let var = |var: i32| {
  println!("{var}")
};
var(2); // 2

let add_two = |var: i32| -> i32 {
  let result = var + 2;
  result
}

let result = add_two(3); // result: i32 = 5

Garbage collector

O Rust não possui garbage collector. Invés disso, a linguagem utiliza o conceito de ownership, borrowing e lifetimes.

Exemplos:

fn main() {
  fn receive_string_and_print(var: String) {
    println!("{var}");
  }
  
  let var = String::from("string");
  
  receive_i32_and_print(var);
  
  println!("{var}");
}
error[E0382]: borrow of moved value: `var`
  --> src/main.rs:10:15
   |
6  |     let var = String::from("string");
   |         --- move occurs because `var` has type `String`, which does not implement the `Copy` trait
7  |
8  |     receive_string_and_print(var);
   |                              --- value moved here
9  |
10 |     println!("{var}");
   |               ^^^^^ value borrowed here after move
   |
note: consider changing this parameter type in function `receive_string_and_print` to borrow instead if owning the value isn\'t necessary
  --> src/main.rs:2:38
   |
2  |     fn receive_string_and_print(var: String) {
   |        ------------------------      ^^^^^^ this parameter takes ownership of the value
   |        |
   |        in this function
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider cloning the value if the performance cost is acceptable
   |
8  |     receive_string_and_print(var.clone());
   |                                 ++++++++

For more information about this error, try `rustc --explain E0382`.
error: could not compile `introduction` (bin "introduction") due to previous error

Estruturas

struct MyStruct;

struct MyStructWithProp {
  prop: i32,
}

impl MyStructWithProp {
  fn add_two(&mut self) {
    self.prop += 2;
  }
}

struct MyStructWithTuple(i32, i32);

impl MyStructWithTuple {
  fn add_two(&mut self) {
    self.0 += 2;
    self.1 += 2;
  }
}

Enums

enum Color {
  Red,
  Green,
  Blue,
}

let my_color = Color::Green;

enum SocketEvent {
    Connected { id: i32 },
    Disconnected { id: i32 },
    ReceiveMessage { id: i32, message: String },
    SendMessage { id: i32, message: String, to: i32 },
}

fn handle_socket_event(socket_event: SocketEvent) {
    match socket_event {
        SocketEvent::Connected { id } => handle_connect(id),
        SocketEvent::ReceiveMessage { id, message } => handle_receive_message(id, message),
        _ => (),
    }
}

Traits

trait Animal {
  fn make_sound(&self) -> &str;
}

struct Dog;
impl Animal for Dog {
    fn make_sound(&self) -> &str {
        "Woof!"
    }
}

struct Cat;
impl Animal for Cat {
    fn make_sound(&self) -> &str {
        "Meow!"
    }
}
fn reproduce_animal_sound<A: Animal>(animal: A) {
    println!("{}", animal.make_sound());
}

fn main() {
    let dog = Dog {};
    let cat = Cat {};

    reproduce_animal_sound(cat);
    reproduce_animal_sound(dog);
}
trait Animal {
    fn make_sound(&self) -> &str;
}

struct Dog;
// impl Animal for Dog {
//     fn make_sound(&self) -> &str {
//         "Woof!"
//     }
// }

struct Cat;
impl Animal for Cat {
    fn make_sound(&self) -> &str {
        "Meow!"
    }
}

fn reproduce_animal_sound<A: Animal>(animal: A) {
    println!("{}", animal.make_sound());
}

fn main() {
    let dog = Dog {};
    let cat = Cat {};

    reproduce_animal_sound(cat);
    reproduce_animal_sound(dog);
}
error[E0277]: the trait bound `Dog: Animal` is not satisfied
  --> src/main.rs:28:28
   |
28 |     reproduce_animal_sound(dog);
   |     ---------------------- ^^^ the trait `Animal` is not implemented for `Dog`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `Animal` is implemented for `Cat`
note: required by a bound in `reproduce_animal_sound`
  --> src/main.rs:19:30
   |
19 | fn reproduce_animal_sound<A: Animal>(animal: A) {
   |                              ^^^^^^ required by this bound in `reproduce_animal_sound`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `introduction` (bin "introduction") due to previous error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment