下面的代码可以成功编译:
然而,以下代码无法编译:
struct StructA<F>(F);
impl<F, T> StructA<F> where F: Fn() -> T {}
T
虽然没有出现在StructA
的类型参数中,但由于where
从句的约束,它仍然受到限制。例如,在std::iter::Map
中就使用了这个技巧,因此Map<I,F>
只需要两个类型参数,而impl<B,I,F> Iterator for Map<I,F>
则需要三个。然而,以下代码无法编译:
struct StructB<F>(F);
impl<F, T> StructB<F> where F: Fn(T) -> T {}
error[E0207]: the type parameter `B` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:5:9
|
5 | impl<F, T> StructB<F> where F: Fn(T) -> T {}
| ^ unconstrained type parameter
For more information about this error, try `rustc --explain E0207`.
error: could not compile `playground` due to previous error
这很不直观,为什么使用更多的T
会使其约束更少?这是故意的还是Rust的限制?
请注意,这也会发生在常规特性中,即Fn
的展开版本:
trait FnTrait<Args> {
type Output;
}
// Works
struct StructA<F>(F);
impl<F, T> StructA<F> where F: FnTrait<(), Output = T> {}
// Fails
struct StructB<F>(F);
impl<F, T> StructB<F> where F: FnTrait<(T,), Output = T> {}