- O autor, que usa C++ há mais de 20 anos, apresenta como redescobriu as vantagens do Rust por meio de uma palestra de Matt Godbolt
- No C++, erros causados por confusão de tipos muitas vezes não são devidamente detectados pelo compilador, enquanto o Rust bloqueia isso com rigor em tempo de compilação
- O Rust tem um design vantajoso não apenas para segurança de memória, mas também para evitar o uso incorreto de APIs
- Especialmente no tratamento de entradas em tempo de execução, o Rust reduz riscos ao forçar o tratamento explícito de erros
- No fim, este é um caso que mostra como o design da linguagem pode ser uma ferramenta poderosa para evitar erros dos desenvolvedores
Introdução
- A palestra de Matt Godbolt, "Correct by Construction", destaca problemas de design de APIs em C++, algo que também está alinhado com a filosofia do Rust
- Para entender os pontos fortes do Rust, esta palestra é um bom material introdutório
What's in a type — os limites do C++
- Uma assinatura de função como
void sendOrder(const char *symbol, bool buy, int quantity, double price) é muito propensa a erros
- Se usar apenas tipos básicos como
bool, int e double, o compilador não avisa mesmo quando o tipo passado está errado
- Aliases de tipo como
using Price = double não oferecem distinção real entre tipos
- Ao criar
Quantity e Price com classes e construtores explicit, o compilador consegue detectar alguns erros, mas:
- valores negativos continuam sendo permitidos, e isso só vira problema em tempo de execução
- com
static_assert e templates, é possível forçar verificações em tempo de compilação
- ainda assim, conversões em tempo de execução como
atoi podem causar overflow de inteiro, e o compilador não detecta isso
Como o Rust é diferente?
- Mesmo com uma definição de função equivalente, o Rust marca claramente incompatibilidades de tipo como erro em tempo de compilação
- Definir novos tipos como
struct Price(pub f64); struct Quantity(pub u64); também é simples, e bloquear entradas negativas funciona de forma natural
- Em conversões de string em tempo de execução como
"string".parse::<u64>(), é necessário tratar erros explicitamente
- Se você desembrulhar o valor à força com
.expect(), haverá um crash em tempo de execução, mas o texto destaca que isso ainda é melhor do que erros silenciosos no C++
Conclusão
- O Rust protege o desenvolvedor não apenas com estabilidade de memória, mas também com prevenção de uso incorreto de APIs, verificações em tempo de compilação e um sistema de tipos claro
- Mostra como o poder do design de linguagem pode evitar erros do desenvolvedor antes que aconteçam
- Iniciantes em Rust podem ter dificuldade ao lidar com o borrow checker, mas isso tende a ser superado com o tempo
- O C++ evoluiu muito historicamente, mas ainda fica evidente que é difícil oferecer a mesma segurança e clareza fundamentais que o Rust
Referência
4 comentários
A maior parte do que costuma ser apontado como desvantagem do C++ aparentemente existe porque precisa ser mantida por causa da compatibilidade com C.
Será que daria para abandonar a compatibilidade com C e mudar a linguagem para que fosse possível desenvolver assim?
Teria sido melhor se não tivesse oferecido
unsafe.linguagem raiz = Rust
Comentários do Hacker News
A maior vantagem do Rust é o tipo
Result, que padroniza a forma de propagação de erros. É atraente não precisar se preocupar com exceções ou com diferentes formas de retorno de erro?e à interface funcional deResult, lidar com erros fica divertido e fácilHá muitas reclamações sobre C++. Em especial, o problema é que é preciso lembrar de muitas regras, e errar apenas uma pode deixar o código vulnerável
O código C++ que escrevo atualmente é parecido com Rust. Uso tipagem explícita e forte, gerenciamento claro de tempo de vida etc.
O problema das conversões implícitas em C++ é mais da biblioteca do que da linguagem
No Rust, é inconveniente usar structs
Args/Optionsporque não há argumentos nomeados nem tuplas com nomesA opção
-Wconversionpode detectar certos problemas de conversão, mas não se aplica a todos os casosO ponto em que Rust é melhor é que não há conversões numéricas implícitas. Em C++, é melhor não usar
atoie sim as funções de conversão da STLAinda não há em Rust ou Golang algo semelhante às constraints do SQL ou aos tipos personalizados e validadores do pydantic
Se você tem interesse no podcast de programação de Matt e Ben Rady, "Two's Complement", vale a pena ouvir