在julia中抛出错误和返回错误之间的区别

时间:2020-10-24 19:58:15

标签: error-handling julia

在给定条件的情况下,这两段代码导致抛出相同的错误:

function f1(x)
  if x > 2
    return x
  else
    return error("x <= 2")
  end
end

function f2(x)
  if x > 2
    return x
  else
    throw(error("x <= 2"))
  end
end

当x <= 2时,f1f2都出错,但是我找不到为什么偏爱一个而不是另一个的任何区别。更进一步,这三段代码返回相同的结果:

error(2)
throw(2)
throw(error(2))

是否有关于如何使用throw vs直接返回错误的指南?

1 个答案:

答案 0 :(得分:5)

error本身会引发错误。来自documentation

error(message::AbstractString)

使用给定的消息引发ErrorException。

因此,无需返回它(如在您的f1函数中)或自己将其抛出(如在f2中);在这两种情况下,error都将在您到达手写returnthrow之前抛出异常。

throw(error(2))error(2)之间的比较也是如此:throw在这里毫无用处,这两个表达式应该做同样的事情(即使堆栈跟踪是相同的)。


关于error(2)throw(2),从表面上看,他们确实做着相同的事情(堆栈跟踪略有不同):

julia> error(2)
ERROR: 2
Stacktrace:
 [1] error(::Int64) at ./error.jl:42
 [2] top-level scope at REPL[8]:1

julia> throw(2)
ERROR: 2
Stacktrace:
 [1] top-level scope at REPL[10]:1

但这只是因为REPL用这种情况下无法区分的方式漂亮地打印了错误。实际上,throw引发了您将其作为参数传递的确切含义:在这种情况下为整数2。而error将其参数字符串化,并在引发它之前将其包装在ErrorException对象中。可以通过捕获异常并dump对其进行查看:

julia> try
         error(2)
       catch e
         dump(e)
       end
ErrorException
  msg: String "2"

julia> try
         throw(2)
       catch e
         dump(e)
       end
Int64 2

总之,我会说

  • 如果要引发error,请使用ErrorException,这是一般的异常,并带有消息字符串。当错误注定是人为的时候,这对于IMO来说就足够了。如果这样做,请仅致电error;否则,请致电。不要returnthrow
  • 要控制引发的异常类型时,请使用throw。例如:throw(BoundsError(my_array, idx))。这样的异常可能更容易捕获并以编程方式处理堆栈中的某些功能。或者,如果未捕获到消息,它可能至少会向用户传达更具体的消息。