异常处理 #

一、异常基础 #

1.1 try-catch语法 #

julia
try
    statements
catch e
    handle_error(e)
end

1.2 基本示例 #

julia
try
    x = 1 / 0
catch e
    println("Error: $e")
end

1.3 捕获特定异常 #

julia
try
    parse(Int, "abc")
catch e
    if e isa ArgumentError
        println("Invalid argument")
    else
        rethrow()
    end
end

二、抛出异常 #

2.1 throw #

julia
function divide(a, b)
    b == 0 && throw(DivideError())
    return a / b
end

divide(10, 0)

2.2 error #

julia
function validate_age(age)
    age < 0 && error("Age cannot be negative")
    age > 150 && error("Age seems unrealistic")
    return age
end

validate_age(-1)

2.3 内置异常类型 #

julia
throw(ArgumentError("Invalid argument"))
throw(DomainError(-1, "sqrt expects non-negative"))
throw(ErrorException("Something went wrong"))
throw(BoundsError([1, 2, 3], 5))
throw(DivideError())

三、异常类型 #

3.1 异常层次 #

text
Exception
├── ArgumentError
├── BoundsError
├── CompositeException
├── DivideError
├── DomainError
├── EOFError
├── ErrorException
├── InexactError
├── InitError
├── InterruptException
├── InvalidStateException
├── KeyError
├── LoadError
├── OutOfMemoryError
├── ReadOnlyMemoryError
├── RemoteException
├── MethodError
├── OverflowError
├── ParseError
├── StackOverflowError
├── SystemError
├── TypeError
├── UndefKeywordError
├── UndefRefError
├── UndefVarError
└── StringIndexError

3.2 常用异常 #

julia
ArgumentError("message")
DomainError(value, "message")
BoundsError(array, index)
KeyError(key)
MethodError(f, args)
TypeError(:func, :arg, expected, got)
UndefVarError(:variable)

四、finally块 #

4.1 基本用法 #

julia
file = nothing
try
    file = open("data.txt", "r")
    process(file)
catch e
    println("Error: $e")
finally
    file !== nothing && close(file)
end

4.2 资源清理 #

julia
function process_file(filename)
    file = open(filename, "r")
    try
        return read(file, String)
    finally
        close(file)
    end
end

五、自定义异常 #

5.1 定义异常类型 #

julia
struct MyError <: Exception
    message::String
    code::Int
end

Base.showerror(io::IO, e::MyError) = print(io, "MyError($(e.code)): $(e.message)")

5.2 使用自定义异常 #

julia
function process(x)
    x < 0 && throw(MyError("Value cannot be negative", 1001))
    return sqrt(x)
end

try
    process(-1)
catch e
    if e isa MyError
        println("Code $(e.code): $(e.message)")
    else
        rethrow()
    end
end

六、异常处理模式 #

6.1 默认值 #

julia
function safe_parse(s, default=nothing)
    try
        parse(Int, s)
    catch
        default
    end
end

safe_parse("123", 0)
safe_parse("abc", 0)

6.2 重试机制 #

julia
function with_retry(f, max_attempts=3)
    for attempt in 1:max_attempts
        try
            return f()
        catch e
            attempt == max_attempts && rethrow()
            println("Attempt $attempt failed: $e")
            sleep(1)
        end
    end
end

6.3 错误累积 #

julia
function validate_all(validators)
    errors = String[]
    for (name, validator) in validators
        try
            validator()
        catch e
            push!(errors, "$name: $e")
        end
    end
    return errors
end

七、实践练习 #

7.1 练习1:安全除法 #

julia
function safe_divide(a, b)
    try
        a / b
    catch e
        if e isa DivideError
            return Inf
        else
            rethrow()
        end
    end
end

safe_divide(10, 2)
safe_divide(10, 0)

7.2 练习2:文件处理 #

julia
function read_config(filename)
    try
        content = read(filename, String)
        return eval(Meta.parse(content))
    catch e
        if e isa SystemError
            println("File not found: $filename")
            return Dict{String, Any}()
        else
            println("Parse error: $e")
            rethrow()
        end
    end
end

7.3 练习3:输入验证 #

julia
struct ValidationError <: Exception
    field::Symbol
    message::String
end

function validate_user(data)
    isempty(get(data, :name, "")) && throw(ValidationError(:name, "Name is required"))
    age = get(data, :age, 0)
    age < 0 && throw(ValidationError(:age, "Age cannot be negative"))
    age > 150 && throw(ValidationError(:age, "Age seems unrealistic"))
    return true
end

try
    validate_user(Dict(:name => "", :age => 25))
catch e
    if e isa ValidationError
        println("Validation failed: $(e.field) - $(e.message)")
    end
end

八、总结 #

本章我们学习了:

  1. try-catch:捕获和处理异常
  2. throw和error:抛出异常
  3. 异常类型:内置和自定义异常
  4. finally:资源清理
  5. 异常处理模式:默认值、重试、累积

接下来让我们学习Julia的函数!

最后更新:2026-03-27