Sobrecarga de Operadores
Rust sobrecarrega operadores por meio de traits em std::ops (Add, Sub, Mul, Index, etc.), mantendo a sintaxe familiar sem "mágica" oculta.
Receita
use std::ops::Add;
#[derive(Clone, Copy, Debug)]
struct Vec2 { x: f32, y: f32 }
impl Add for Vec2 {
type Output = Vec2;
fn add(self, rhs: Self) -> Self::Output {
Self { x: self.x + rhs.x, y: self.y + rhs.y }
}
}Quando usar: Tipos de domínio onde +, [] ou * correspondem a semânticas matemáticas ou de contêiner.
Exemplo de Trabalho
use std::ops::{Add, Index};
struct Matrix<T> { data: Vec<T>, cols: usize }
impl<T: Copy + Add<Output = T>> Add for Matrix<T> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
let data = self.data.iter().zip(&rhs.data)
.map(|(a, b)| *a + *b).collect();
Self { data, cols: self.cols }
}
}
impl<T> Index<usize> for Matrix<T> {
type Output = T;
fn index(&self, i: usize) -> &Self::Output { &self.data[i] }
}O que isso demonstra:
Addcom tipo associadoOutputIndexpara sintaxe[]- Limites no parâmetro de tipo para adição elemento a elemento
Análise Detalhada
Traits comuns: Add, Sub, Mul, Div, Rem, Neg, Not, BitAnd, Shl, Index, IndexMut, Deref.
Armadilhas
- Semântica confusa -
+para um significado não relacionado prejudica a legibilidade. Correção: Métodos nomeados para operações incomuns. - Esquecer o tipo
Output- Tipo associado obrigatório. Correção:type Output = Selfé comum. - Variantes
Add<&Self>- Pode precisar de uma segunda implementação para referências. Correção: Implementar separadamente para possuídos e referências, se necessário. Indexque entra em pânico - Deve corresponder às regras de slice ou usarget. Correção: Documentar o contrato de pânico.- Operações automáticas vs. manuais -
+=usaAddAssign. Correção: Implementar ambos para ergonomia.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Métodos .add() | Significado de operador incerto | Tipos matemáticos naturais |
| Padrão Builder | Construção, não adição | Matemática vetorial |
| Macros | Sintaxe específica de DSL | Operações padrão adequadas |
FAQs
+= requer?
`AddAssign` trait.Operadores de comparação?
`PartialEq`, `PartialOrd` - não são traits de operações.Precedência personalizada?
Não é possível alterar a precedência da linguagem.rhs de referência?
`impl Add<&Vec2> for Vec2` etc.Comutatividade?
Não é imposta - documentar se for importante.Float PartialEq?
Separado dos traits de operador.IndexMut?
Permite `m[i] = v`.Coerção Deref?
`Deref`/`DerefMut` habilitam operações de ponteiro inteligente.ops `no_std`?
`core::ops` mesmos traits.clippy?
Lints em implementações com tipos incomuns.Relacionados
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.