Pular para o conteúdo principal
ProdutosFerramentas de desktopTASTECADVisualização de desenhosTASTEFILESGerenciamento de arquivosTASTEFTPTransferência de arquivosTASTESSHEspaço de trabalho remotoTASTEZIPCompactação e extraçãoFerramentas para desenvolvedoresTASTECODEAmbiente de desenvolvimento integrado para RustTASTESTUDIOAmbiente integrado de desenvolvimento e testesTASTEETLIntegração de dados (ETL)ServidoresTASTEREMOTEServidor de área de trabalho remotaTASTEGEOServidor geoespacialTASTEMAILEspaço de trabalho de e-mailComeçarDownloadsDocumentaçãoComprarTodos os produtos
Marketplace
Notícias
TecnologiaNotíciasNotícias de desenvolvimento de hojeDocumentaçãoLinguagens de programaçãoRustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartFrameworks de front-end webNext.jsReactVue.js · NuxtSvelteKitAngularFrameworks de servidorSpring BootDjangoFastAPIASP.NET CoreNestJS · ExpressFrameworks de apps e desktopTauriFlutterReact NativeElectronAlgoritmosFundamentos de algoritmosAlgoritmos essenciaisAlgoritmos avançadosAlgoritmos práticos
ComunidadeProjetosRegistros de desenvolvimentoPromptsProblemas de ferramentas de IAVitrineGuia da comunidade
ColaboreTransferência técnicaConstrução de siteConstrução de app de desktopPipeline de lançamento e pagamentoParceiro de vendasContato
ServiçosÁrea de trabalho remotaPacotes de instalação sob medida
TASTEDEV
Produtos

Ferramentas de desktop

TASTECADDesenhos complexos, abertos com levezaTASTEFILESSó os arquivos de que você precisa, o mais rápido possívelTASTEFTPO caminho mais organizado para seus arquivosTASTESSHEntre você e o servidor, uma conexão mais sólidaTASTEZIPCompacte mais rápido, extraia com mais segurança

Ferramentas para desenvolvedores

TASTECODEEdite, compile, depure e teste apps Rust em uma única janelaTASTESTUDIODa edição aos testes remotos e às correções com IA aprovadasTASTEETLMova dados de olho nos valores

Servidores

TASTEREMOTEUma área de trabalho remota rodando no seu próprio servidorTASTEGEOUm servidor geoespacial compatível com o GeoServer, reconstruído em RustTASTEMAILRetome o controle do seu e-mail

Começar

DownloadsVersões mais recentes de cada produtoDocsComo usar cada produtoComprarAssinaturas e licenças perpétuasTodos os produtosTodos os produtos de relance
Todos os produtos
MarketplaceNotícias
Tecnologia

Notícias

Notícias de desenvolvimento de hojeAnúncios oficiais de linguagens, frameworks, GitHub e IADocumentaçãoGuias de linguagens, frameworks e algoritmos

Linguagens de programação

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

Frameworks

Frameworks de front-end webNext.jsReactVue.js · NuxtSvelteKitAngular
Frameworks de servidorSpring BootDjangoFastAPIASP.NET CoreNestJS · Express
Frameworks de apps e desktopTauriFlutterReact NativeElectron

Algoritmos

Fundamentos de algoritmosAnálise de complexidade · Ordenação · Busca · Estruturas de dados básicas · Árvores e heapsAlgoritmos essenciaisBusca em grafos · Caminho mínimo e árvore geradora mínima · Programação dinâmica · Algoritmos gulosos · Divisão e conquista · BacktrackingAlgoritmos avançadosAlgoritmos de strings · Matemática e teoria dos números · Manipulação de bits · Árvores de segmentos · Union-FindAlgoritmos práticosEstratégia para entrevistas de código · Cache LRU · Limitação de taxa · Hashing consistente
Toda a documentação de desenvolvimento
Comunidade
ProjetosDescubra criadores e trabalhosRegistros de desenvolvimentoDecisões e aprendizadosPromptsInstruções reutilizáveisProblemas de ferramentas de IAProblemas e contornos de Claude, Codex, GeminiVitrineResultados concluídosGuia da comunidadeComo construímos em aberto
Colabore
Transferência técnicaApps nativos em Rust e eguiConstrução de site10 idiomas, contas, documentação e downloadsConstrução de app de desktopRust e egui, sem WebViewPipeline de lançamento e pagamentoAssinatura, MSI, deb, rpm, AppImage, hashesParceiro de vendasRecomende e ganhe 30%ContatoDesenvolvimento, parcerias e investimento
Serviços
Área de trabalho remotaAcesse seu computador pelo navegadorPacotes de instalação sob medidaSó o necessário, configurações pré-carregadas
Comprar
PT
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
Entrar
Entrar
TASTEDEV

De pequenas ferramentas a um desenvolvimento melhor.

support@tastedev.netApoiar TASTEDEV
ProdutosLinha de produtosComprarDocsDownloadsMarketplaceSuporte
ComunidadeProjetosRegistros de desenvolvimentoPromptsProblemas de ferramentas de IAVitrine
PolíticasPolítica de privacidadeTermos de usoTermos de assinaturaReembolsoDiretrizes da comunidade
ContaEntrarCriar conta
Visitantes
Hoje
012345678901234567890123456789012345678901234567890123456789
Ontem
012345678901234567890123456789012345678901234567890123456789
Visualizações totais
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
Empresa
GXSOFT
Representante
CHOI YOUNG GU
Número de registro comercial
853-44-00368
Endereço
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
Telefone
+82-10-4404-1523
E-mail
whitecalvin@tastedev.net
Responsável pela privacidade
CHOI YOUNG GU

© 2026 TASTEDEVAs informações dos produtos se baseiam em fontes de desenvolvimento verificadas.Lançado · em melhoria

Documentação de Rust
Rust
Getting Started with RustSyntax BasicsTypes and DataModules and PackagesErrors and TestingKey Concepts: Ownership, Borrowing, Lifetimes, Traits
Discussões

Guia de Rust · 5/6

Errors and Testing

Por enquanto, este capítulo está disponível apenas em inglês.

Rust has no exceptions. Instead it separates two kinds of failure: bugs you cannot recover from stop the program with panic!, while operations that can legitimately fail return a Result that the caller must handle. The second half of this chapter covers the testing tools built into Cargo.

Panics versus recoverable errors

A panic! says "reaching this point means the program has a bug". Indexing past the end of a slice or calling unwrap() on None also panic. For expected failures, like a missing file or malformed input, return Result<T, E>.

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

fn read_config(path: &str) -> Result<String, io::Error> {
    let text = fs::read_to_string(path)?; // on failure, return the error
    Ok(text.trim().to_string())
}

fn main() {
    match read_config("config.txt") {
        Ok(text) => println!("config: {text}"),
        Err(e) => eprintln!("could not read config: {e}"),
    }
}

unwrap() and expect("reason") panic on error. Keep them for examples, tests, and places where failure truly cannot happen, and even then prefer expect so the panic message explains your assumption.

The ? operator

? unwraps an Ok value or returns the Err from the current function immediately. If the error types differ, it converts via From into the function's error type. Inside a function that returns Option, it works on Option values as well.

use std::error::Error;
use std::num::ParseIntError;

fn sum_strs(a: &str, b: &str) -> Result<i32, ParseIntError> {
    let x: i32 = a.trim().parse()?;
    let y: i32 = b.trim().parse()?;
    Ok(x + y)
}

fn first_char_upper(s: &str) -> Option<char> {
    let c = s.chars().next()?; // None for an empty string
    Some(c.to_ascii_uppercase())
}

// main can return a Result; an Err is printed and the exit code signals failure
fn main() -> Result<(), Box<dyn Error>> {
    println!("{}", sum_strs("2", " 40 ")?); // 42
    println!("{:?}", first_char_upper("rust")); // Some('R')
    println!("{:?}", sum_strs("2", "x")); // Err(ParseIntError { .. })
    Ok(())
}

Box<dyn Error> can hold any error type, which makes it a convenient return type for main in small programs.

Custom error types

Libraries usually model their failure modes as an enum so callers can match on them. Implement Display and std::error::Error, and add From impls so ? converts underlying errors automatically.

use std::fmt;
use std::num::ParseIntError;

#[derive(Debug)]
enum AppError {
    Parse(ParseIntError),
    Negative(i64),
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            AppError::Parse(e) => write!(f, "not a number: {e}"),
            AppError::Negative(n) => write!(f, "negative values are not allowed: {n}"),
        }
    }
}

impl std::error::Error for AppError {}

impl From<ParseIntError> for AppError {
    fn from(e: ParseIntError) -> Self {
        AppError::Parse(e)
    }
}

fn parse_positive(s: &str) -> Result<i64, AppError> {
    let n: i64 = s.parse()?; // ParseIntError becomes AppError
    if n < 0 {
        return Err(AppError::Negative(n));
    }
    Ok(n)
}

fn main() {
    for input in ["42", "-7", "abc"] {
        match parse_positive(input) {
            Ok(n) => println!("ok: {n}"),
            Err(e) => println!("error: {e}"),
        }
    }
}
Dúvidas sobre este capítulo?
Capítulo anteriorModules and PackagesPróximo capítuloKey Concepts: Ownership, Borrowing, Lifetimes, Traits

Two popular crates remove most of this boilerplate: thiserror derives error enums for libraries, and anyhow gives applications a single catch-all error type with easy context.

Unit tests

A test is any function marked #[test]. By convention unit tests sit at the bottom of the same file in a #[cfg(test)] module, so they are compiled only when testing. Check results with assert!, assert_eq! and assert_ne!.

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

pub fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        panic!("divide by zero");
    }
    a / b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn adds_two_numbers() {
        assert_eq!(add(2, 3), 5);
    }

    #[test]
    #[should_panic(expected = "divide by zero")]
    fn panics_on_zero() {
        divide(1, 0);
    }

    #[test]
    fn parses_number() -> Result<(), std::num::ParseIntError> {
        let n: i32 = "10".parse()?; // tests may return Result too
        assert_eq!(n, 10);
        Ok(())
    }
}

cargo test and doc tests

cargo test runs unit tests, integration tests in tests/, and code examples inside documentation comments.

cargo test                    # everything
cargo test adds               # only tests whose name contains "adds"
cargo test -- --nocapture     # show println! output
cargo test -- --ignored       # run slow tests marked #[ignore]
cargo test --doc              # doc tests only

Code blocks inside /// comments become documentation and tests at the same time, so examples cannot drift out of date. A package named my-crate is referred to as my_crate in code.

/// Adds two numbers.
///
/// ```
/// let sum = my_crate::add(2, 3);
/// assert_eq!(sum, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Summary

  • Use panic! for bugs and Result for failures the caller should handle.
  • ? propagates errors early and converts them through From.
  • An error enum implementing Display, Error and From makes a pleasant API.
  • #[test] plus cargo test covers unit, integration and doc tests in one command.

0 comentários

Principais comentáriosMais recentes primeiro

Fazer login · Faça login para deixar um comentário.