0
respostas

Rust projeto requisitando Pokemons de uma api - uso da palavra-chave dyn

Opa beleza eu terminei o curso de Rust esses dias e estou fazendo uns projetinhos pequenos pra praticar com a Linguagem, fiz esse projeto que faz a requisição dos 151 pokemons do Kanto.

Eu usei a crate reqwest para fazer as requisições, a tokio para o processamento assincrono (async e await) e a crate serde e serde_json para desserializar o json recebido, só com os campos que me interessavam. Achei interessante que você habilita ou desabilita features a do crates no Cargo.toml

https://github.com/nenodias/pokemon-client-rust

Achei que seria bacana trocar figurinhas por aqui.

Um dos pontos obscuros pra mim é a necessidade da dyn keyword.

[https://doc.rust-lang.org/rust-by-example/trait/dyn.html](Documentação Rust dyn)

O compilador do Rust precisa saber quanto espaço cada tipo de retorno de função precisa.Isso significa que todas as suas funções devem retornar um tipo concreto. Ao contrário de outras linguagens, se você tem uma trait como Animal, você não pode escrever uma função que retorna um Animal, pois cada suas diferentes implementações irão precisar de diferentes quantidades de memória.

Entretanto, existe uma forma de contornar esse problema. Ao invés de retornar um objeto trait diretamente, nossa função retorna um Box no qual contém o objeto da trait Animal. O box é apenas uma referência para a memória na heap. Por ter seu tamanho estaticamente informado, e o compilador pode garantir que sempre aponta para um espaço na heap de um Animal alocado, nós podemos retornar uma trait de nossa função!

Rust tenta ser explícito sempre que possível ao allocar memória na heap. Então se sua função retornar um pointeiro para uma trait dessa maneira, você precisa escrever o tipo de retorno com a palavra-chave dyn , por exemplo. Box.

struct Sheep {}
struct Cow {}

trait Animal {
    // Instance method signature
    fn noise(&self) -> &'static str;
}

// Implement the `Animal` trait for `Sheep`.
impl Animal for Sheep {
    fn noise(&self) -> &'static str {
        "baaaaah!"
    }
}

// Implement the `Animal` trait for `Cow`.
impl Animal for Cow {
    fn noise(&self) -> &'static str {
        "moooooo!"
    }
}

// Returns some struct that implements Animal, but we don't know which one at compile time.
fn random_animal(random_number: f64) -> Box<dyn Animal> {
    if random_number < 0.5 {
        Box::new(Sheep {})
    } else {
        Box::new(Cow {})
    }
}

fn main() {
    let random_number = 0.234;
    let animal = random_animal(random_number);
    println!("You've randomly chosen an animal, and it says {}", animal.noise());
}

[https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7f6c9a3db239495a2f5960ada110419d](Link do código no playground)

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software