这是Into<Option<T>>
Rust 中用于可选参数的常见模式,因为它允许使用用户友好的任一None
或某些来调用函数t: T
。但是我发现这种类型注释有点冗长,所以我想给这个模式取别名。
在 Rust 中稳定真正的特征别名之前,似乎有一个别名特征的黑客:https : //www.worthe-it.co.za/blog/2017-01-15-aliasing-traits-in-rust.html .
在我的情况下如何使用它?我尝试了以下代码:
pub trait Optional<T>:Into<Option<T>>{}
impl<T> Optional<T> for T where T: Into<Option<T>>{}
fn main(){
add(3.0, None);
add(1.0, 2.0);
}
fn add<T: Optional<f64>>(a: f64, b: T) -> f64 {
let b = match b.into() {
Some(b) => b,
None => 0.0
};
a + b
}
但是编译器说:
error[E0277]: the trait bound `Option<_>: Optional<f64>` is not satisfied
--> test.rs:5:14
|
5 | add(3.0, None);
| ^^^^ the trait `Optional<f64>` is not implemented for `Option<_>`
...
9 | fn add<T: Optional<f64>>(a: f64, b: T) -> f64 {
| ------------- required by this bound in `add`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
很明显,hack 不起作用,因为编译器无法检测到任何f64
或None
应该实现此接口。
如何修复此别名以使其正确编译?
这里涉及两个类型参数。T
是可选值的类型,因此f64
在您的示例中。所以
impl<T> Optional<T> for T where T: Into<Option<T>>{}
只执行Optional<f64> for f64
. 但是您也想为其他类型实现它,因此您需要使用不同的类型参数。尝试
impl<T, U> Optional<T> for U where U: Into<Option<T>> {}
现在终于可以为( ), ( ) 和任何其他类型实现Optional<f64>
( T=f64
) 了。f64
U=f64
Option<f64>
U=Option<f64>
Into<Option<T>>
......我应该把它写成
impl<ValueT, ConvertibleT> Optional<ValueT> for ConvertibleT
where ConvertibleT: Into<Option<ValueT>>
因为字母T
和具有多个参数的泛型没有什么特别之处,所以它们的参数应该像通常为函数参数所做的那样正确命名。
(游乐场)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句