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

Python Vs Rust Error Handling

O documento compara o tratamento de erros em Python e Rust, destacando que Python utiliza exceções enquanto Rust adota um modelo explícito com Result<T, E> e Option<T>. Em Rust, erros são tratados como valores retornados, forçando o programador a lidar com eles, ao contrário do comportamento de exceções em Python. O texto também aborda a utilização de métodos como ? e a implementação de tipos de erro personalizados em Rust.
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)
7 visualizações19 páginas

Python Vs Rust Error Handling

O documento compara o tratamento de erros em Python e Rust, destacando que Python utiliza exceções enquanto Rust adota um modelo explícito com Result<T, E> e Option<T>. Em Rust, erros são tratados como valores retornados, forçando o programador a lidar com eles, ao contrário do comportamento de exceções em Python. O texto também aborda a utilização de métodos como ? e a implementação de tipos de erro personalizados em Rust.
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, 16:08 Python vs Rust Error Handling

Sou programador Python aprendendo Rust, tenha ótima


didática e faça correlação entre as linguagens, mostre
como o rust trabalha com Error Handling

Pensou por alguns segundos

Claro. Vamos fazer isso do jeito certo: comparando Python com Rust, porque isso acelera
muito o aprendizado quando você já programa bem em Python.

Visão geral
Em Python, tratamento de erro normalmente gira em torno de:

try
except

raise

exceções em tempo de execução

Em Rust, o tratamento de erro é mais explícito, seguro e previsível.


A ideia principal é:
erros esperados → usar Result<T, E>
ausência de valor → usar Option<T>
erros irrecuperáveis → panic!

Ou seja, em Rust você geralmente não “pega exceções” como em Python.


Você modela o erro no tipo de retorno.

1. Comparação mental: Python vs Rust


Python

def dividir(a, b):


return a / b

try:
print(dividir(10, 0))

[Link] 1/19
09/03/2026, 16:08 Python vs Rust Error Handling

except ZeroDivisionError as e:
Python Executar
print(f"Erro: {e}")

Aqui a função não diz no tipo que pode falhar.


Você só descobre isso pela documentação ou pela experiência.

Rust

fn dividir(a: f64, b: f64) -> Result<f64, String> {


if b == 0.0 {
Err("divisão por zero".to_string())
} else {
Ok(a / b)
}
}

Aqui o tipo já informa:

Ok(f64) → sucesso

Err(String) → falha

Isso força quem chama a função a lidar com o erro.

2. O tipo Result<T, E>


Esse é o coração do error handling em Rust.

Estrutura

enum Result<T, E> {


Ok(T),
Err(E),
}
Rust
Pense assim:

T = tipo do valor de sucesso

E = tipo do erro

Exemplo simples

[Link] 2/19
09/03/2026, 16:08 Python vs Rust Error Handling

fn converter_numero(txt: &str) -> Result<i32, std::num::ParseIntError> {


[Link]::<i32>()
}
Rust

Uso:

fn main() {
let resultado = converter_numero("123");

match resultado {
Ok(valor) => println!("Número convertido: {}", valor),
Err(erro) => println!("Falha ao converter: {}", erro),
}
}

3. Correlação direta com Python


Python: exceção

def converter_numero(txt):
return int(txt)

try:
n = converter_numero("abc")
except ValueError as e:
print("Erro:", e)

Rust: retorno explícito

fn converter_numero(txt: &str) -> Result<i32, std::num::ParseIntError> {


[Link]::<i32>()
}
Rust

Diferença conceitual:
Python: erro “explode” e você captura depois
Rust: erro volta como valor e você decide o que fazer

[Link] 3/19
09/03/2026, 16:08 Python vs Rust Error Handling

Essa diferença é enorme.


Em Rust, erro é dado, não evento excepcional invisível.

4. match : a forma mais explícita de tratar erro


Em Rust, match é o equivalente mental mais forte para “tratar todos os casos”.

fn dividir(a: f64, b: f64) -> Result<f64, String> {


if b == 0.0 {
Err("divisão por zero".to_string())
} else {
Ok(a / b)
}
}

fn main() {
match dividir(10.0, 2.0) {
Ok(resultado) => println!("Resultado: {}", resultado),
Err(msg) => println!("Erro: {}", msg),
}
}

Leitura didática
dividir(...) retorna Result

match obriga você a tratar:

Ok(resultado)

Err(msg)

Isso evita esquecer casos de falha.

5. O operador ? : o mais importante para quem vem do


Python
Depois que você entende Result , o próximo passo essencial é o ? .

Ele serve para:

pegar o valor de Ok(...)


ou retornar o erro imediatamente se vier Err(...)

[Link] 4/19
09/03/2026, 16:08 Python vs Rust Error Handling

Exemplo

use std::num::ParseIntError;

fn somar_textos(a: &str, b: &str) -> Result<i32, ParseIntError> {


let x = [Link]::<i32>()?;
let y = [Link]::<i32>()?;
Ok(x + y)
}

fn main() {
match somar_textos("10", "20") {
Ok(soma) => println!("Soma: {}", soma),
Err(e) => println!("Erro: {}", e),
}
}

O que ? faz aqui

let Rust
x = [Link]::<i32>()?;

É quase como se fosse:

let x = match [Link]::<i32>() {


Ok(valor) => valor,
Err(e) => return Err(e),
};
Rust

Correlação com Python


Em Python, você poderia fazer assim:

def somar_textos(a, b):


x = int(a)
y = int(b)
return x + y
Python Executar
Se falhar, sobe exceção.

[Link] 5/19
09/03/2026, 16:08 Python vs Rust Error Handling

Em Rust:

a falha não sobe “misteriosamente”


ela volta pelo Result
o ? simplifica a propagação

6. unwrap() e expect() : use com cuidado


Esses métodos existem, mas você precisa entender quando usar.

unwrap()

fn main() {
let n = "123".parse::<i32>().unwrap();
println!("{}", n);
}
Rust
Se der erro, o programa panica e termina.

expect()

fn main() {
let n = "abc".parse::<i32>().expect("Era esperado um número inteiro válido");
println!("{}", n);
}
Rust
 

Se falhar, mostra uma mensagem mais clara.

Equivalência mental com Python


É parecido com fazer algo que você assume que sempre vai funcionar, mas sem tratar erro
adequadamente.

Em código Python, seria como:

[Link] 6/19
09/03/2026, 16:08 Python vs Rust Error Handling

n = Python
int("abc") # explode se falhar Executar

Regra prática
Use unwrap() ou expect() quando:

em testes
em protótipos
em casos realmente garantidos
em inicialização de dados fixos que você controla

Evite em código de produção para entradas externas.

7. Option<T> : quando não é erro, é ausência


Nem toda ausência de valor é erro.

Exemplo em Python

def buscar_nome(id_):
banco = {1: "Ana", 2: "Carlos"}
return [Link](id_)
Python Executar

Aqui get pode retornar None .

Em Rust

fn buscar_nome(id: u32) -> Option<&'static str> {


match id {
1 => Some("Ana"),
2 => Some("Carlos"),
_ => None,
}
}

Uso:

[Link] 7/19
09/03/2026, 16:08 Python vs Rust Error Handling

fn main() {
match buscar_nome(3) {
Some(nome) => println!("Nome: {}", nome),
None => println!("Usuário não encontrado"),
}
} Rust

Correlação
Python None
Rust Option
Some(valor)
None

8. Quando usar Option e quando usar Result


Essa parte é crucial.

Use Option quando:


a ausência é normal e esperada.

Exemplos:

procurar chave em mapa


pegar primeiro elemento de lista
buscar item que pode não existir

Use Result quando:


há uma falha que precisa ser explicada.

Exemplos:

erro ao abrir arquivo


erro ao converter string para número
erro de rede
entrada inválida

9. Exemplo real: leitura de arquivo


Python
[Link] 8/19
09/03/2026, 16:08 Python vs Rust Error Handling

def ler_arquivo(caminho):
with open(caminho, "r", encoding="utf-8") as f:
return [Link]()

try:
conteudo = ler_arquivo("[Link]")
print(conteudo)
except FileNotFoundError:
print("Arquivo não encontrado")
except OSError as e:
print("Erro de I/O:", e)

Rust

use std::fs;
use std::io;

fn ler_arquivo(caminho: &str) -> Result<String, io::Error> {


fs::read_to_string(caminho)
}

fn main() {
match ler_arquivo("[Link]") {
Ok(conteudo) => println!("{}", conteudo),
Err(e) => println!("Erro ao ler arquivo: {}", e),
}
}

10. Propagando erro com ? em arquivo

use std::fs;
use std::io;

fn ler_e_contar(caminho: &str) -> Result<usize, io::Error> {


let conteudo = fs::read_to_string(caminho)?;
Ok([Link]().count())
}

fn main() {

[Link] 9/19
09/03/2026, 16:08 Python vs Rust Error Handling

match ler_e_contar("[Link]") {
Ok(qtd) => println!("Linhas: {}", qtd),
Err(e) => println!("Erro: {}", e),
}
}

Explicação
read_to_string(...) retorna Result<String, io::Error>

? pega o String se der certo

se falhar, retorna Err(io::Error) automaticamente

11. Criando seus próprios tipos de erro


Aqui Rust fica muito poderoso.

Forma simples com String

fn validar_idade(idade: i32) -> Result<(), String> {


if idade < 0 {
Err("idade não pode ser negativa".to_string())
} else if idade < 18 {
Err("idade menor que 18".to_string())
} else {
Ok(())
}
}

Isso funciona, mas não é o ideal para sistemas maiores.

Forma melhor com enum

#[derive(Debug)]
enum ErroValidacao {
IdadeNegativa,
MenorDeIdade,
}

fn validar_idade(idade: i32) -> Result<(), ErroValidacao> {


if idade < 0 {
Err(ErroValidacao::IdadeNegativa)
[Link] 10/19
09/03/2026, 16:08 Python vs Rust Error Handling

} else if idade < 18 {


Err(ErroValidacao::MenorDeIdade)
} else {
Ok(())
}
}

fn main() {
match validar_idade(15) {
Ok(()) => println!("Idade válida"),
Err(erro) => println!("Erro: {:?}", erro),
}
}

Correlação com Python


Em Python, você poderia criar exceções customizadas:

class IdadeNegativaError(Exception):
pass

class MenorDeIdadeError(Exception):
pass
P th E t
Em Rust, você normalmente usa enum para representar as variantes do erro.

Isso é muito elegante porque:

é fortemente tipado
é explícito
é fácil usar com match

12. Implementando Display para erro customizado


Para exibir mensagens bonitas:

use std::fmt;

#[derive(Debug)]
enum ErroValidacao {
IdadeNegativa,
[Link] 11/19
09/03/2026, 16:08 Python vs Rust Error Handling

MenorDeIdade,
}

impl fmt::Display for ErroValidacao {


fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ErroValidacao::IdadeNegativa => write!(f, "idade não pode ser negativ
ErroValidacao::MenorDeIdade => write!(f, "usuário deve ser maior de i
}
}
}

fn validar_idade(idade: i32) -> Result<(), ErroValidacao> {


if idade < 0 {
Err(ErroValidacao::IdadeNegativa)
} else if idade < 18 {
Err(ErroValidacao::MenorDeIdade)
} else {
Ok(())
}
}

fn main() {
match validar_idade(10) {
Ok(()) => println!("Tudo certo"),
Err(e) => println!("Erro: {}", e),
}
}

Agora o erro aparece de forma amigável.

13. panic! : erro irrecuperável


panic! encerra o programa.

fn main() {
panic!("algo deu muito errado");
}
Rust

Também acontece implicitamente com unwrap() quando falha.

Quando pensar em panic!


Use quando:
é bug de programação

[Link] 12/19
09/03/2026, 16:08 Python vs Rust Error Handling

estado impossível aconteceu


invariantes internas foram violadas

Não use para fluxo comum de aplicação


Por exemplo:
entrada inválida do usuário
arquivo ausente
falha de rede

Esses casos pedem Result , não panic! .

14. Comparação prática de filosofia


Python
Muito ergonômico, rápido para escrever.
Mas pode esconder caminhos de erro se você não ler a documentação.

Rust
Mais verboso no começo.
Mas te obriga a modelar corretamente o que pode falhar.

Isso reduz uma classe enorme de bugs.

15. Padrão muito comum em Rust


Você verá isso o tempo todo:

fn fazer_algo() -> Result<(), Box<dyn std::error::Error>> {


Ok(())
}
Rust

O que significa
() = sucesso sem valor relevante

Box<dyn Error> = tipo genérico para vários erros

Exemplo:

[Link] 13/19
09/03/2026, 16:08 Python vs Rust Error Handling

use std::fs;
use std::error::Error;

fn processar() -> Result<(), Box<dyn Error>> {


let conteudo = fs::read_to_string("[Link]")?;
let numero: i32 = [Link]().parse()?;
println!("Número: {}", numero);
Ok(())
}

fn main() {
if let Err(e) = processar() {
println!("Erro: {}", e);
}
}

Boa analogia com Python


É parecido com uma função que pode falhar por vários motivos diferentes:
arquivo
parse
formato

Só que em Rust você torna isso explícito no tipo.

16. if let para casos simples


Às vezes match é verboso.
Você pode usar if let .

Exemplo com Result

fn main() {
let resultado = "42".parse::<i32>();

if let Ok(numero) = resultado {


println!("Número: {}", numero);
} else {
println!("Falhou");
}
}

[Link] 14/19
09/03/2026, 16:08 Python vs Rust Error Handling

Exemplo com Option

fn main() {
let nome = Some("Gandra");

if let Some(n) = nome {


println!("Olá, {}", n);
}
}

17. Resumo mental para decorar


Guarde isso:

Em Python
erro costuma ser tratado com try/except
exceções podem surgir “depois”

Em Rust
erro esperado = Result<T, E>
ausência = Option<T>
falha fatal = panic!
propagação elegante = ?

18. Exemplo lado a lado: Python e Rust


Python

def ler_numero_arquivo(caminho):
with open(caminho, "r", encoding="utf-8") as f:
return int([Link]().strip())

try:
n = ler_numero_arquivo("[Link]")
print(n)
except FileNotFoundError:
print("Arquivo não encontrado")
except ValueError:

[Link] 15/19
09/03/2026, 16:08 Python vs Rust Error Handling

print("Conteúdo inválido")
except OSError as e:
print("Erro de I/O:", e)

Rust

use std::fs;
use std::error::Error;

fn ler_numero_arquivo(caminho: &str) -> Result<i32, Box<dyn Error>> {


let conteudo = fs::read_to_string(caminho)?;
let numero = [Link]().parse::<i32>()?;
Ok(numero)
}

fn main() {
match ler_numero_arquivo("[Link]") {
Ok(n) => println!("{}", n),
Err(e) => println!("Erro: {}", e),
}
}

19. O que mais confunde quem vem do Python


Aqui estão os pontos que mais pegam:

1. “Por que Rust não usa exceção igual Python?”


Porque Rust quer que o compilador ajude a garantir que você tratou falhas possíveis.

2. “Tudo vira Result ?”


Não tudo. Só o que pode falhar de forma esperada.

3. “Então panic! é igual exception?”


Não exatamente. panic! é mais próximo de um aborto controlado por erro grave.

4. “ ? é tipo try/except?”
Não.
Ele é mais um atalho para propagação de erro.

[Link] 16/19
09/03/2026, 16:08 Python vs Rust Error Handling

20. Regra de ouro para pensar como Rustacean


Quando criar uma função, pergunte:

A falta de valor é normal?


Use Option<T> .

A falha precisa de explicação?


Use Result<T, E> .

Isso representa bug ou estado impossível?


Use panic! apenas se fizer sentido.

21. Exemplo final, bem idiomático

use std::fs;
use std::error::Error;

fn carregar_idade(caminho: &str) -> Result<u8, Box<dyn Error>> {


let conteudo = fs::read_to_string(caminho)?;
let idade: u8 = [Link]().parse()?;

if idade > 130 {


return Err("idade inválida: maior que 130".into());
}

Ok(idade)
}

fn main() {
match carregar_idade("[Link]") {
Ok(idade) => println!("Idade carregada: {}", idade),
Err(e) => eprintln!("Falha ao carregar idade: {}", e),
}
}

O que esse exemplo mostra


leitura de arquivo pode falhar
conversão para número pode falhar
validação de domínio também pode falhar
tudo isso é encadeado com Result

[Link] 17/19
09/03/2026, 16:08 Python vs Rust Error Handling

22. Mapa mental final

Python
try/except
raise
exceptions em runtime

Rust
Result<T, E> -> erro esperado
Option<T> -> ausência de valor
? -> propaga erro
match -> trata explicitamente
unwrap/expect -> falha imediata
panic! -> erro irrecuperável

23. Conselho prático para você evoluir rápido


Como você já programa em Python, a melhor estratégia é esta:
1. pare de pensar em exceção
2. pense em tipo de retorno
3. ao escrever função em Rust, sempre pergunte:
pode faltar valor?
pode falhar?
esse erro deve subir?
4. use match no começo
5. depois migre para ? quando entender bem

Essa transição é o ponto em que Rust começa a “clicar” na mente de quem vem do
Python.

24. Exercício ideal para treinar


Implemente em Rust estas 3 funções:
ler um arquivo texto
converter conteúdo para inteiro
dividir 100 por esse inteiro

E trate os casos:
[Link] 18/19
09/03/2026, 16:08 Python vs Rust Error Handling

arquivo não existe


conteúdo inválido
divisão por zero

Isso vai te obrigar a usar:

Result

match

erro de domínio

Se você quiser, no próximo passo eu posso montar para você um mini projeto em Rust
comparado com Python, mostrando Result , Option , match , ? , unwrap , expect e
erro customizado em um exemplo único e progressivo.

[Link] 19/19

Você também pode gostar