Error handling 为什么在长生不老药中有两种表示错误的方法?

Error handling 为什么在长生不老药中有两种表示错误的方法?,error-handling,elixir,Error Handling,Elixir,一些Elixir函数有两种变体用于指示错误 返回一个元组,例如File.open,它返回类似{:ok,io\u device}或{:error,posix} 引发异常,例如File.open 我的问题是: 有两种方式的目的是什么 一种方法是否优于另一种方法(如最佳实践) 有两种处理错误的方法,因为有两种类型的错误: 预期的错误-如用户提供错误数据等。在这种情况下,使用元组样式的返回值来处理错误。这也迫使调用方考虑错误情况并正确处理。 真正出乎意料的异常——比如配置文件突然消失,无法从中恢复,除

一些Elixir函数有两种变体用于指示错误

  • 返回一个元组,例如
    File.open
    ,它返回类似
    {:ok,io\u device}
    {:error,posix}

  • 引发异常,例如
    File.open

  • 我的问题是:

  • 有两种方式的目的是什么
  • 一种方法是否优于另一种方法(如最佳实践)
    有两种处理错误的方法,因为有两种类型的错误:

    • 预期的错误-如用户提供错误数据等。在这种情况下,使用元组样式的返回值来处理错误。这也迫使调用方考虑错误情况并正确处理。
    • 真正出乎意料的异常——比如配置文件突然消失,无法从中恢复,除了崩溃之外没什么可做的。在这种情况下,您将引发一个异常
    由于这两种方式,您很少会发现自己需要援救异常——在其他语言中,您希望援救异常,而在Elixir中,您首先避免引发异常,而是返回ok/error元组

    我想说元组风格更优越,因为它给了调用者控制权——调用者可以通过对
    case
    表达式中的返回值进行模式匹配并处理这两种可能性,或者忽略错误的一种,直接对
    ok
    元组进行模式匹配来决定如何处理错误。如果发生意外错误,第二个将把返回值转换为
    MatchError
    异常。您可以看到如何轻松地将第一种样式转换为第二种样式。也就是说,许多库提供了“bang”函数,这些函数会引发错误,以便于使用,并且能够提供比普通的
    MatchError
    所允许的更好的错误消息

    虽然
    {:ok,value}
    通常与
    {:error,reason}
    成对出现,但这只是一种约定。有许多API只返回
    :error
    而没有原因,原因很明显,也有一些API在成功的情况下返回不同的结果。这里的规则是提供一个不依赖顺序的简单模式匹配。让我们看一些例子:

    {value, rest} | :error
    
    这是一个很好的选择,因为案例很容易区分——例如,
    Integer.parse/2
    使用这种样式。如果成功条件有两个返回值,并且失败原因只有一个,则建议使用此样式

    string | :error
    

    这似乎不是一个好主意,您要么需要在模式匹配中有一个防护装置,要么首先小心匹配
    :error
    atom。相反,可以将成功值包装在
    {:ok,string}
    元组中以便于使用。

    有两种处理错误的方法,因为有两种类型的错误:

    • 预期的错误-如用户提供错误数据等。在这种情况下,使用元组样式的返回值来处理错误。这也迫使调用方考虑错误情况并正确处理。
    • 真正出乎意料的异常——比如配置文件突然消失,无法从中恢复,除了崩溃之外没什么可做的。在这种情况下,您将引发一个异常
    由于这两种方式,您很少会发现自己需要援救异常——在其他语言中,您希望援救异常,而在Elixir中,您首先避免引发异常,而是返回ok/error元组

    我想说元组风格更优越,因为它给了调用者控制权——调用者可以通过对
    case
    表达式中的返回值进行模式匹配并处理这两种可能性,或者忽略错误的一种,直接对
    ok
    元组进行模式匹配来决定如何处理错误。如果发生意外错误,第二个将把返回值转换为
    MatchError
    异常。您可以看到如何轻松地将第一种样式转换为第二种样式。也就是说,许多库提供了“bang”函数,这些函数会引发错误,以便于使用,并且能够提供比普通的
    MatchError
    所允许的更好的错误消息

    虽然
    {:ok,value}
    通常与
    {:error,reason}
    成对出现,但这只是一种约定。有许多API只返回
    :error
    而没有原因,原因很明显,也有一些API在成功的情况下返回不同的结果。这里的规则是提供一个不依赖顺序的简单模式匹配。让我们看一些例子:

    {value, rest} | :error
    
    这是一个很好的选择,因为案例很容易区分——例如,
    Integer.parse/2
    使用这种样式。如果成功条件有两个返回值,并且失败原因只有一个,则建议使用此样式

    string | :error
    
    这似乎不是一个好主意,您要么需要在模式匹配中有一个防护装置,要么首先小心匹配
    :error
    atom。相反,为了便于使用,可以将success值包装在
    {:ok,string}
    元组中