正常程序执行期间发生的任何意外情况都称为异常。 Julia 中的异常处理是一种机制,可以通过确定一条替代路径来继续正常程序执行来克服这种情况。如果异常没有得到处理,程序会突然终止。程序不知道发生异常时要执行的操作。避免编译器在此类异常上崩溃的过程称为异常处理。
异常处理
Julia 允许通过使用 try-catch 块进行异常处理。可能抛出异常的代码块放在 try 块中,catch 块处理抛出的异常。异常通过调用堆栈传播,直到找到 try-catch 块。让我们考虑下面的代码,在这里我们尝试找到抛出“DomainError”并且程序终止的 -1 的平方根。
println(sqrt(-1))
输出:
ERROR: LoadError: DomainError:
sqrt will only return a complex result if called with a complex argument. Try sqrt(complex(x)).
Stacktrace:
[1] sqrt(::Int64) at ./math.jl:434
while loading /home/cg/root/945981/main.jl, in expression starting on line 1
如果没有 try-catch 块,程序会突然终止。但是,我们可以通过使用 try-catch 块优雅地处理异常来防止程序终止。
println("Before Exception")
try
sqrt(-1)
catch
println("Cannot find the square root of negative numbers")
end
println("After Exception")
输出:
Before Exception
Cannot find the square root of negative numbers
After Exception
try-catch 块还允许将异常存储在变量中。使用catch块处理多种异常的方法称为Canonical方法。如果 x 可索引,以下示例计算 x 的第三个元素的平方根,否则假定 x 是实数并返回其平方根。
sqrt_third(x) = try
println(sqrt(x[3]))
catch y
if isa(y, DomainError)
println(sqrt(complex(x[3], 0)))
elseif isa(y, BoundsError)
println(sqrt(x))
end
end
sqrt_third([1 9 16 25])
sqrt_third([1 -4 9 16])
sqrt_third(25)
sqrt_third(-9)
输出:
4.0
3.0
5.0
ERROR: LoadError: DomainError:
Stacktrace:
[1] sqrt_third(::Int64) at /home/cg/root/945981/main.jl:7
while loading /home/cg/root/945981/main.jl, in expression starting on line 15
finally 子句的使用
无论是否发生异常,finally 块都会运行。 finally 块中的代码可用于关闭资源,如打开的文件或其他清理工作。
try
f = open("file.txt")
catch
println("No such file exists")
finally
println("After exception")
end
输出:
No such file exists
After exception
抛出异常
throw()
函数可用于抛出自定义异常。以下示例显示从函数抛出并由 catch 块处理的错误。 error()
函数用于产生一个 ErrorException。
function f(x)
if(x < 5)
throw(error())
end
return sqrt(x)
end
try
println(f(9))
println(f(1))
catch e
println("Argument less than 5")
end
输出:
3.0
Argument less than 5
异常也可以从 catch 块中抛出。 catch 块可能包含一些代码来处理捕获的异常,然后重新抛出异常。此异常必须由同一方法中的另一个 try-catch 块或调用堆栈中的任何其他方法处理。如果未捕获异常,则异常会一直传播到主函数。
function f(x)
if(x < 5)
throw(error())
end
return sqrt(x)
end
try
println(f(9))
println(f(1))
catch e
println("Argument less than 5")
throw(error())
end
输出:
3.0
Argument less than 5
ERROR: LoadError:
Stacktrace:
[1] error() at ./error.jl:30
while loading /home/cg/root/945981/main.jl, in expression starting on line 13
从 catch 块抛出错误
function f(x)
if(x < 5)
throw(error())
end
return sqrt(x)
end
try
try
println(f(9))
println(f(1))
catch e
println("Argument less than 5")
throw(error())
end
catch e
println("Second catch block")
end
输出:
3.0
Argument less than 5
Second catch block
一行尝试捕获
try sqrt(x) catch y end
这意味着尝试 sqrt(x),如果抛出异常,则将其传递给变量 y。
现在如果必须返回存储在 y 中的值,那么 catch 后面必须跟一个分号。
try sqrt(x) catch; y end
try println(sqrt(-9)) catch; y end
输出:
ERROR: LoadError: UndefVarError: y not defined
while loading /home/cg/root/945981/main.jl, in expression starting on line 1
内置异常
Julia 提供了一些内置的异常,如下所示:
Exception | Description |
---|---|
ArgumentError | This exception is thrown when the parameters to a function call do not match a valid signature. |
BoundsError | This exception is thrown if there the user tries to access anarray index beyond the index range. |
CompositeException | This exception provides information about each subtask that throws exception within a task. |
DimensionMismatch | This exception is thrown when objects called do not have matching dimensionality. |
DivideError | This exception is thrown when the user tries to divide by 0(zero). |
DomainError | This exception is thrown when the argument to a function or constructor does not lie in the valid domain. |
EOFError | This exception is thrown when there is no more data left to read in a file. |
ErrorException | This exception is thrown to indicate generic error. |
InexactError | This exception is thrown when the program cannot exactly convert a particular value to type T in a method. |
InitError | This exception is thrown when an error occurs while running __init__ function of a module. |
InterruptException | This exception is thrown when a process is stopped from the terminal using CTRL+C . |
InvalidStateException | This exception is thrown when the program runs into an invalid state. |
KeyError | This exception is thrown when when a user tries to access or delete a non-existing element from AbstractDict or Set. |
LoadError | This exception is thrown if an error occurs while importing or using a file. |
OutOfMemoryError | This exception is thrown when a program exceeds the available system memory. |
ReadOnlyMemoryError | This exception is thrown when a program tries to write a memory that is read-only. |
RemoteException | This exception is thrown when exception of a remote computer is thrown locally. The exception specifies the pid of the worker and the corresponding exception. |
MethodError | This exception is thrown when a method with the required type signature does not exist. |
OverflowError | This exception is thrown when result of an expression is too large for the specified type and causes a wrap-around. |
Meta.ParseError | This exception is thrown when an expression passed to the parse function cannot be interpreted as a valid Julia expression. |
SystemError | This exception is thrown when a system call fails. |
TypeError | This exception is thrown when a type assertion fails, or an intrinsic function is called with incorrect argument type. |
UndefRefError | This exception is thrown if an item or field is not defined for the specified object. |
UndefVarError | This exception is thrown when a symbol is not defined in the current scope. |
StringIndexError | This exception is thrown when the user tries to access a string index that exceeds the string length. |