Traits AssĂncronos
Métodos async em traits foram estabilizados apenas recentemente, no lançamento 1.75. Isso exigiu suporte para o uso de impl Trait
em posição de retorno em traits, pois a "desaçucarização" para async fn
inclui -> impl Future<Output = ...>
.
No entanto, mesmo com o suporte nativo hoje, existem algumas armadilhas em torno de async fn
e RPIT em _traits:
-
O
impl Trait
em posição de retorno captura todos os tempos de vida em escopo (portanto, alguns padrÔes de empréstimo não podem ser expressos) -
Os métodos de traits que usam
impl trait
em posição de retorno ouasync
nĂŁo sĂŁo compatĂveis comdyn
.
Se precisarmos de suporte dyn
, o crate async_trait fornece uma solução alternativa por meio de um macro, com algumas ressalvas:
use async_trait::async_trait; use std::time::Instant; use tokio::time::{sleep, Duration}; #[async_trait] trait Sleeper { async fn sleep(&self); } struct FixedSleeper { sleep_ms: u64, } #[async_trait] impl Sleeper for FixedSleeper { async fn sleep(&self) { sleep(Duration::from_millis(self.sleep_ms)).await; } } async fn run_all_sleepers_multiple_times( sleepers: Vec<Box<dyn Sleeper>>, n_times: usize, ) { for _ in 0..n_times { println!("executando todos os dormentes.."); for sleeper in &sleepers { let start = Instant::now(); sleeper.sleep().await; println!("dormiu por {}ms", start.elapsed().as_millis()); } } } #[tokio::main] async fn main() { let sleepers: Vec<Box<dyn Sleeper>> = vec![ Box::new(FixedSleeper { sleep_ms: 50 }), Box::new(FixedSleeper { sleep_ms: 100 }), ]; run_all_sleepers_multiple_times(sleepers, 5).await; }
-
async_trait
é fåcil de usar, mas observe que ele estå usando alocaçÔes de pilha para alcançar isso. Essa alocação de pilha impacta o desempenho. -
Os desafios no suporte da linguagem para
async trait
sĂŁo profundos em Rust e provavelmente nĂŁo valem a pena descrever em detalhes. Niko Matsakis fez um bom trabalho ao explicĂĄ-los neste post se vocĂȘ estiver interessado em aprofundar. -
Tente criar uma nova estrutura sleeper que dormirĂĄ por uma quantidade aleatĂłria de tempo e adicionĂĄ-la ao Vec.