为什么在 Rust 中使用动态错误而不是枚举很常见? bad/not 可以使用编译时变体吗?
Why is it common to use dynamic errors in rust, and not enums? Is it bad/not possible to use compile-time variants?
我在 Rust 中看到这种趋势,Result
中的错误返回如下:
fn do_something() -> Result<SomeType, Box<dyn std::error::Error>> {
// ...
}
为什么错误是动态的?来自 C++ 背景并且更喜欢 std::variant
而不是经典多态性(我对 rust 比较陌生),我对动态分配过敏,所以我只在真正需要的时候使用它们。我还发现 Rust 的枚举在其中包含变体非常棒。有人可以解释为什么 standard/preferred/common 不使用错误作为枚举吗?
在应用程序代码中,这样做通常是为了方便。使所有错误类型静态已知可能是维护的噩梦:您有一个不断扩展的可能错误类型的枚举,其中大多数您永远不会尝试单独处理。这些错误类型有一种方法可以在远离错误实际发生位置的地方污染类型签名。 Box<dyn std::error::Error>
让事情变得非常干净,额外的分配通常不是问题,因为它只发生在错误情况下。
它在库包中很少见,但一些非常通用的代码不可能知道所有可能的错误类型。在组合多个结果类型时,处理错误的类型参数会变得非常笨拙。可能的静态已知错误组合的复杂结构可以方便地折叠成单一类型,Box<dyn std::error::Error>
.
我在 Rust 中看到这种趋势,Result
中的错误返回如下:
fn do_something() -> Result<SomeType, Box<dyn std::error::Error>> {
// ...
}
为什么错误是动态的?来自 C++ 背景并且更喜欢 std::variant
而不是经典多态性(我对 rust 比较陌生),我对动态分配过敏,所以我只在真正需要的时候使用它们。我还发现 Rust 的枚举在其中包含变体非常棒。有人可以解释为什么 standard/preferred/common 不使用错误作为枚举吗?
在应用程序代码中,这样做通常是为了方便。使所有错误类型静态已知可能是维护的噩梦:您有一个不断扩展的可能错误类型的枚举,其中大多数您永远不会尝试单独处理。这些错误类型有一种方法可以在远离错误实际发生位置的地方污染类型签名。 Box<dyn std::error::Error>
让事情变得非常干净,额外的分配通常不是问题,因为它只发生在错误情况下。
它在库包中很少见,但一些非常通用的代码不可能知道所有可能的错误类型。在组合多个结果类型时,处理错误的类型参数会变得非常笨拙。可能的静态已知错误组合的复杂结构可以方便地折叠成单一类型,Box<dyn std::error::Error>
.