在一篇博客文章中,Rust 贡献者 withoutboats 提到:
我的大多数具有许多返回路径的函数都以
match语句终止。从技术上讲,这些可以通过将整个比赛包装在一个Ok.
一个(有点人为的)例子——
坏的:
Ok(match response {
UserResponse(user) => user,
ItemResponse(item) => item?,
})
Run Code Online (Sandbox Code Playgroud)
更好的:
match response {
UserResponse(user) => Ok(user),
ItemResponse(item) => Ok(item?),
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
这是一个很难回答的问题。我个人不记得以前见过任何人表达过这种意见。公平地说,我不能说我听过相反的话。也就是说,我不记得有人明确鼓励在代码中使用这种模式。
我以前肯定使用过这种模式,虽然有点谨慎。为了演示,这通常发生在当您有一个match包含多个 case 的表达式返回 a Result,并且您不想Ok为每个 case编写时。像这样:
Ok(match something {
Something::Foo => 1,
Something::Bar => 2,
Something::Quux => fallible?,
Something::Baz => return Err(...),
})
Run Code Online (Sandbox Code Playgroud)
与
match something {
Something::Foo => Ok(1),
Something::Bar => Ok(2),
Something::Quux => fallible,
Something::Baz => Err(...),
}
Run Code Online (Sandbox Code Playgroud)
这不是一个巨大的差异,但如果你有很多Ok案例,它可能会有点烦人。或者至少,这是Boat 博客文章中的主要抱怨(为Ok-wrapping辩护)。
这个图案的另一种变型为1)时的函数返回Result,2)函数的尾部表达也是一个Result,3)的错误类型不相同,并且4)在(1)的错误类型具有From用于IMPL (2) 中的错误类型。也就是说,而不是写
something.fallible().map_err(From::from)
Run Code Online (Sandbox Code Playgroud)
一个可以写
Ok(something.fallible()?)
Run Code Online (Sandbox Code Playgroud)
? 无处不在,以至于我总是将它们之间的差异归结为个人风格。
我不可能知道博客作者在说这是一种糟糕的形式时是怎么想的。我的猜测——我有点同意这一点——是手臂之间缺乏对称性match表达式。其中一些实际上是早期回报,而另一些则根本不是早期回报。我可以看到有些人会如何看待这种不和谐。
否则,我偶尔会使用这两种模式,但不是虔诚的。如果它出现并且有意义,那么我对它没有太大的问题。
| 归档时间: |
|
| 查看次数: |
373 次 |
| 最近记录: |