Sobes.tech
Junior

Como detectar erros em Swift?

sobes.tech IA

Resposta da IA

No Swift, os erros são capturados usando um sistema de tratamento de erros baseado no uso das palavras-chave throw, throws, try e do bloco do-catch.

  1. Declaração de funções que podem lançar erros: Usa-se a palavra-chave throws após os parâmetros da função.

    enum DataError: Error {
        case emptyData
        case invalidFormat
    }
    
    func processData(input: String) throws -> String {
        guard !input.isEmpty else {
            throw DataError.emptyData // Lança um erro
        }
        // ...lógica de processamento de dados...
        if input == "invalid" {
             throw DataError.invalidFormat
        }
        return "Processed: \(input)"
    }
    
  2. Chamada de funções que podem lançar erros: Usa-se a palavra-chave try.

    do { // Bloco para tratar erros
        let result = try processData(input: "dados válidos")
        print(result) // "Processed: dados válidos"
    } catch { // Bloco para capturar erros
        print("Ocorreu um erro: \(error)")
    }
    
  3. Captura de tipos específicos de erros: No bloco catch, pode-se indicar um tipo de erro específico para captura.

    do {
        let result = try processData(input: "")
        print(result)
    } catch DataError.emptyData {
        print("Os dados estão vazios, por favor forneça entrada.")
    } catch DataError.invalidFormat {
        print("O formato dos dados é inválido.")
    } catch { // Captura quaisquer outros erros
        print("Ocorreu um erro inesperado: \(error)")
    }
    
  4. Bloco defer: É executado imediatamente antes de sair do escopo atual, independentemente de uma exceção ter ocorrido ou não. Frequentemente usado para liberar recursos.

    func openFile(_ filename: String) throws -> String {
        // Suponha que isso abre um arquivo e retorna seu conteúdo
        print("Abrindo arquivo \(filename)")
        // ... lógica de abertura ...
    
        defer {
            // Este código será executado antes de sair da função,
            // mesmo que ocorra um erro
            print("Fechando arquivo \(filename)")
        }
    
        // ... processamento do arquivo ...
        if filename == "error.txt" {
           throw DataError.invalidFormat // Lança um erro
        }
    
        return "Conteúdo do arquivo"
    }
    
    do {
        let content = try openFile("data.txt")
        print(content)
    } catch {
        print("Erro ao manipular o arquivo: \(error)")
    }
    
  5. try? opcional: Retorna um valor opcional. Se a função lançar um erro, try? retorna nil.

    let processedResult = try? processData(input: "") // processedResult será nil
    let validResult = try? processData(input: "abc") // validResult será uma String opcional com o valor "Processed: abc"
    
  6. try! forçado: Usado quando você tem certeza de que o erro não ocorrerá. Se ocorrer um erro, o aplicativo terminará abruptamente. Use com cautela.

    // Use apenas se tiver 100% de certeza de que a função não lançará erro
    let result = try! processData(input: "sempre entrada válida")
    

O sistema baseado em do-catch é uma forma mais explícita e segura de tratar erros em comparação com as exceções tradicionais em outras linguagens, pois exige declarar explicitamente funções que podem lançar erros (throws) e tratar esses erros de forma explícita ao chamá-las (try, do-catch).