Rust中实现始终返回Err的Result时,T类型该用什么?
在Rust中为永远返回Err的Result指定类型参数T的惯用方式
当你的trait实现永远只会返回Err、绝不会返回Ok时,类型参数T应该指定为**std::convert::Infallible,或者在Rust 1.61及以上版本中使用原生的never类型!**——这两种类型都是Rust里用来表示「永远不会存在实例的类型」,完美匹配“永远不会返回Ok”的语义。
为什么选这两种类型?
Infallible和!的核心意义就是标记某个值不可能出现。既然你的bar函数永远不会返回Ok(Self::T),那T的类型自然应该是一个不可能被实例化的类型,这完全符合语义逻辑,同时编译器也能识别这种情况:比如当调用者尝试匹配Ok分支时,编译器会提示该分支不可达,避免无效代码。
具体实现代码
下面是补全后的示例:
use std::error::Error; use std::fmt; #[derive(Debug)] struct MyCustomError; // 为MyCustomError实现Error trait的必要依赖 impl Error for MyCustomError {} impl fmt::Display for MyCustomError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "自定义错误") } } trait Foo { type T; type E: Error; fn bar() -> Result<Self::T, Self::E>; } // 方式1:使用Infallible impl Foo for MyCustomError { type T = std::convert::Infallible; type E = MyCustomError; fn bar() -> Result<Self::T, Self::E> { Err(MyCustomError) } } // 方式2:使用never类型!(Rust 1.61+支持) impl Foo for MyCustomError { type T = !; type E = MyCustomError; fn bar() -> Result<Self::T, Self::E> { Err(MyCustomError) } }
两者的关系
标准库中的Infallible本质上是!的类型别名:pub type Infallible = !;,所以两者功能完全等价。选择哪种取决于个人习惯:Infallible的名称更具语义性,一眼就能看懂含义;!则更简洁。
内容的提问来源于stack exchange,提问作者bartop
相关产品推荐
相关产品推荐

