0% acharam este documento útil (0 voto)
2 visualizações15 páginas

Python Rust Box Trait

O documento explica a correlação entre Python e Rust, focando no uso de Box<dyn Trait> em Rust para implementar polimorfismo dinâmico. Ele detalha como traits em Rust funcionam como interfaces, a necessidade de Box para gerenciar tamanhos dinâmicos e compara a abordagem de Rust com a de Python. Além disso, são discutidas as diferenças entre genéricos e dyn Trait, e quando usar cada um, finalizando com exemplos práticos.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
2 visualizações15 páginas

Python Rust Box Trait

O documento explica a correlação entre Python e Rust, focando no uso de Box<dyn Trait> em Rust para implementar polimorfismo dinâmico. Ele detalha como traits em Rust funcionam como interfaces, a necessidade de Box para gerenciar tamanhos dinâmicos e compara a abordagem de Rust com a de Python. Além disso, são discutidas as diferenças entre genéricos e dyn Trait, e quando usar cada um, finalizando com exemplos práticos.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

09/03/2026, 15:47 Python Rust Box Trait

Sou programador Python aprendendo Rust, tenha ótima


didática e faça correlação entre as linguagens, mostre
como o rust trabalha com Box<dyn Trait>

Pensou por dois segundos

Claro — vamos fazer a ponte Python → Rust de um jeito bem prático.

Ideia central
Em Python, você está acostumado com polimorfismo dinâmico:

class Animal:
def falar(self):
raise NotImplementedError

class Cachorro(Animal):
def falar(self):
return "au au"

class Gato(Animal):
def falar(self):
return "miau"

animais = [Cachorro(), Gato()]

for a in animais:
print([Link]())

Aqui, a lista guarda objetos diferentes e o Python resolve tudo em tempo de execução.

No Rust, isso também existe, mas de forma explícita e segura.


É aí que entra:

Box<dyn Trait>
Rust

O que significa Box<dyn Trait>


[Link] 1/15
09/03/2026, 15:47 Python Rust Box Trait

Vamos quebrar em partes:

1. Trait
Um trait no Rust é parecido com uma interface/contrato.

Exemplo:

trait Animal {
fn falar(&self) -> String;
}
Rust

Isso diz: “qualquer tipo que implemente Animal precisa ter o método falar ”.

2. dyn Trait
dyn Trait significa despacho dinâmico.

Ou seja: o compilador não sabe exatamente qual tipo concreto está ali, mas sabe que ele
implementa aquele trait.

É parecido com pensar assim em Python:

# "qualquer objeto que tenha esse comportamento"


Python Executar

Mas no Rust isso é tipado e controlado.

3. Box<T>
Box<T> é um ponteiro inteligente que aloca o valor no heap.

Isso é necessário porque dyn Trait tem tamanho desconhecido em tempo de


compilação.

Rust precisa saber o tamanho dos valores em muitas situações. Como dyn Trait pode
apontar para tipos diferentes, o tamanho concreto varia.
Então colocamos dentro de um Box , que tem tamanho fixo conhecido.

[Link] 2/15
09/03/2026, 15:47 Python Rust Box Trait

Regra prática
Sem Box
Você geralmente usa quando o tipo é conhecido em tempo de compilação.

Com Box<dyn Trait>


Você usa quando quer guardar tipos diferentes no mesmo lugar, desde que todos
implementem o mesmo trait.

Exemplo completo
Definindo o trait e os tipos

trait Animal {
fn falar(&self) -> String;
}

struct Cachorro;
struct Gato;

impl Animal for Cachorro {


fn falar(&self) -> String {
"au au".to_string()
}
}

impl Animal for Gato {


fn falar(&self) -> String {
"miau".to_string()
}
}

Guardando vários tipos em um vetor

fn main() {
let animais: Vec<Box<dyn Animal>> = vec![
Box::new(Cachorro),
Box::new(Gato),
];
[Link] 3/15
09/03/2026, 15:47 Python Rust Box Trait

for animal in [Link]() {


println!("{}", [Link]());
}
}

Correlação direta com Python


Esse trecho Rust:

let Rust
animais: Vec<Box<dyn Animal>>

é conceitualmente parecido com:

animais:
Pythonlist[Animal] Executar

Só que com diferenças importantes:

Python
tudo é naturalmente referência para objeto
o polimorfismo é natural e dinâmico
pouca preocupação com layout de memória

Rust
o compilador quer saber tamanhos e ownership
tipos diferentes têm tamanhos diferentes
para unificar isso, usamos dyn Trait
para armazenar isso de forma concreta, usamos Box

Por que não posso fazer Vec<dyn Animal> ?


Porque dyn Animal é um tipo de tamanho dinâmico.

Rust precisa que os elementos do Vec tenham tamanho conhecido.


Como um Cachorro e um Gato podem ter representações diferentes, dyn Animal
sozinho não serve como elemento direto.

[Link] 4/15
09/03/2026, 15:47 Python Rust Box Trait

Então fazemos:

Vec<Box<dyn
Rust Animal>>

Agora o vetor guarda Boxes, e todo Box tem tamanho conhecido.

Analogia simples
Imagine isso:
Trait = o contrato

dyn Trait = “algum tipo que segue esse contrato”


Box = uma caixa com endereço fixo apontando para esse valor no heap

Então:

Box<dyn
Rust Animal>

significa:

“uma caixa contendo algum valor concreto que implementa Animal , mesmo que eu
não saiba exatamente qual tipo é agora”.

Como funciona por baixo


Box<dyn Trait> usa algo parecido com uma fat pointer:

ponteiro para os dados reais


ponteiro para a tabela de métodos ( vtable )

Isso permite que, em tempo de execução, Rust saiba qual implementação chamar.

É parecido com despacho dinâmico orientado a objetos.

Quando você faz:

[Link]()
Rust

[Link] 5/15
09/03/2026, 15:47 Python Rust Box Trait

em Box<dyn Animal> , Rust consulta essa tabela e chama a implementação certa.

Comparação importante: genéricos vs dyn Trait


Essa diferença é muito importante em Rust.

1. Usando genéricos

fn emitir_som<T: Animal>(animal: T) {
println!("{}", [Link]());
}
Rust

Vantagens
mais rápido em muitos casos
despacho estático
otimizações melhores

Limitação
cada chamada trabalha com um tipo concreto
não serve bem para coleções heterogêneas

2. Usando dyn Trait

fn emitir_som(animal: &dyn Animal) {


println!("{}", [Link]());
}
Rust

Vantagens
flexível
aceita qualquer tipo que implemente o trait
útil para coleções heterogêneas

Custo
despacho dinâmico
pequena indireção extra

[Link] 6/15
09/03/2026, 15:47 Python Rust Box Trait

Quando usar cada um


Use genéricos quando:
o tipo pode ser conhecido em compilação
você quer mais performance
não precisa misturar vários tipos concretos na mesma estrutura

Use Box<dyn Trait> quando:


precisa guardar tipos diferentes juntos
quer comportamento mais orientado a objetos
está modelando plugins, handlers, estratégias, etc.

Exemplo com função recebendo trait object


Referência para trait object

trait Animal {
fn falar(&self) -> String;
}

struct Cachorro;

impl Animal for Cachorro {


fn falar(&self) -> String {
"au au".to_string()
}
}

fn apresentar(animal: &dyn Animal) {


println!("O animal diz: {}", [Link]());
}

fn main() {
let cachorro = Cachorro;
apresentar(&cachorro);
}

Aqui usamos:

[Link] 7/15
09/03/2026, 15:47 Python Rust Box Trait

&dynRust
Animal

em vez de:

Box<dyn
Rust Animal>

Diferença
&dyn Animal → empréstimo
Box<dyn Animal> → ownership

Correlação com referência em Python


Em Python, praticamente tudo já é uma referência para objeto.
Em Rust, você escolhe explicitamente:

&dyn Trait → “usar sem tomar posse”

Box<dyn Trait> → “possuir o objeto alocado no heap”

Exemplo mais próximo de arquitetura real


Vamos imaginar estratégias de pagamento.

Python

class Pagamento:
def pagar(self, valor):
raise NotImplementedError

class Pix(Pagamento):
def pagar(self, valor):
print(f"Pagando R$ {valor} via Pix")

class Cartao(Pagamento):
def pagar(self, valor):
print(f"Pagando R$ {valor} via Cartão")

Rust com Box<dyn Trait>


[Link] 8/15
09/03/2026, 15:47 Python Rust Box Trait

trait Pagamento {
fn pagar(&self, valor: f64);
}

struct Pix;
struct Cartao;

impl Pagamento for Pix {


fn pagar(&self, valor: f64) {
println!("Pagando R$ {} via Pix", valor);
}
}

impl Pagamento for Cartao {


fn pagar(&self, valor: f64) {
println!("Pagando R$ {} via Cartão", valor);
}
}

fn main() {
let metodos: Vec<Box<dyn Pagamento>> = vec![
Box::new(Pix),
Box::new(Cartao),
];

for metodo in [Link]() {


[Link](150.0);
}
}

Isso é extremamente útil para:


strategy pattern
handlers
plugins
middlewares
motores de regra

Limitação importante: object safety


Nem todo trait pode virar dyn Trait .

Para isso, o trait precisa ser object safe.

Exemplo problemático
[Link] 9/15
09/03/2026, 15:47 Python Rust Box Trait

trait Exemplo {
fn criar() -> Self;
}
Rust

Isso não funciona bem com dyn Trait , porque Self depende do tipo concreto.

Em geral, traits para dyn devem evitar:


métodos que retornem Self
métodos genéricos
certas formas que dependam do tipo concreto

Exemplo de erro conceitual comum


Tentativa errada

trait Animal {
fn falar(&self) -> String;
}

struct Cachorro;
struct Gato;

impl Animal for Cachorro {


fn falar(&self) -> String {
"au au".to_string()
}
}

impl Animal for Gato {


fn falar(&self) -> String {
"miau".to_string()
}
}

fn main() {
let animais = vec![Cachorro, Gato];
}

Isso falha porque o vetor exige elementos do mesmo tipo.


Cachorro e Gato são tipos diferentes.

[Link] 10/15
09/03/2026, 15:47 Python Rust Box Trait

Forma correta

let animais: Vec<Box<dyn Animal>> = vec![


Box::new(Cachorro),
Box::new(Gato),
];
Rust

Outro ponto importante: impl Trait não substitui


Box<dyn Trait> em tudo
Você pode ver algo assim:

fn criar_animal() -> impl Animal {


Cachorro
}
Rust

Isso funciona, mas impl Trait significa:

a função retorna um tipo concreto específico, escondido do chamador.

Ou seja, não é “retorna qualquer tipo a cada chamada”.


É um único tipo concreto por assinatura.

Se você quiser retornar tipos diferentes dependendo da lógica, normalmente entra


Box<dyn Trait> .

Exemplo

trait Animal {
fn falar(&self) -> String;
}

struct Cachorro;
struct Gato;

impl Animal for Cachorro {


fn falar(&self) -> String {
"au au".to_string()
}

[Link] 11/15
09/03/2026, 15:47 Python Rust Box Trait

impl Animal for Gato {


fn falar(&self) -> String {
"miau".to_string()
}
}

fn criar_animal(tipo: &str) -> Box<dyn Animal> {


match tipo {
"cachorro" => Box::new(Cachorro),
"gato" => Box::new(Gato),
_ => Box::new(Cachorro),
}
}

Aqui faz total sentido usar Box<dyn Animal> .

Resumo mental para quem vem do Python


Guarde esta tradução:

Python
“Tenho objetos diferentes, todos com o mesmo comportamento”

Rust
“Tenho tipos diferentes, todos implementando o mesmo trait”

Quando eu quero tratá-los de forma uniforme em runtime:

Box<dyn
Rust Trait>

Fórmula prática
Quer polimorfismo sem posse?

&dynRust
Trait

[Link] 12/15
09/03/2026, 15:47 Python Rust Box Trait

Quer polimorfismo com posse?

Box<dyn
Rust Trait>

Quer performance e tipo conhecido?

T: Trait
Rust

Tabela de comparação
Conceito Python Rust

Contrato de comportamento classe base / protocolo trait


implícito

Polimorfismo dinâmico natural dyn Trait

Referência para objeto implícita &dyn Trait

Objeto com posse natural pelo modelo da Box<dyn Trait>


linguagem

Coleção heterogênea list Vec<Box<dyn Trait>>

Resolução de método runtime runtime com vtable

Exemplo final bem didático

trait Notificador {
fn enviar(&self, msg: &str);
}

struct Email;
struct Sms;

impl Notificador for Email {


[Link] 13/15
09/03/2026, 15:47 Python Rust Box Trait

fn enviar(&self, msg: &str) {


println!("Email enviado: {}", msg);
}
}

impl Notificador for Sms {


fn enviar(&self, msg: &str) {
println!("SMS enviado: {}", msg);
}
}

fn main() {
let notificadores: Vec<Box<dyn Notificador>> = vec![
Box::new(Email),
Box::new(Sms),
];

for n in [Link]() {
[Link]("Olá!");
}
}

Leitura em “linguagem Python”


existe uma interface chamada Notificador
Email e Sms implementam essa interface

o vetor guarda instâncias diferentes


cada uma responde ao mesmo método enviar

Frase para decorar


Box<dyn Trait> = “um objeto no heap, com tipo concreto oculto, acessado por meio

de um contrato comum, com despacho dinâmico”.

Conclusão
Para quem vem de Python, o mais importante é entender:
1. trait é o contrato
2. dyn Trait é o polimorfismo dinâmico
3. Box resolve o problema de tamanho e ownership
4. Vec<Box<dyn Trait>> é o padrão para guardar tipos diferentes com o mesmo
comportamento

[Link] 14/15
09/03/2026, 15:47 Python Rust Box Trait

Posso te mostrar o próximo passo com um exemplo comparando:

Box<dyn Trait>

&dyn Trait

T: Trait
Arc<dyn Trait + Send + Sync>

num cenário real de arquitetura, como plugins, handlers HTTP ou strategy pattern em
Rust.

[Link] 15/15

Você também pode gostar