以下代码可以正常编译:
struct StructA<F>(F);
impl<F, T> StructA<F> where F: Fn() -> T {}
Run Code Online (Sandbox Code Playgroud)
虽然T没有出现在StructA的类型参数中,但它仍然受到该where子句的限制。例如,std::iter::MapsoMap<I, F>只需要两个类型参数,而 the 则impl<B, I, F> Iterator for Map<I, F>需要三个。
但是以下代码无法编译:
struct StructB<F>(F);
impl<F, T> StructB<F> where F: Fn(T) -> T {}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这是不直观的,为什么T在更多地方使用会减少它的限制呢?这是 Rust 有意为之还是限制?
请注意,这也发生在常规特征上,即脱糖版本Fn:
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
Run Code Online (Sandbox Code Playgroud)
考虑一下如果我们手动实现会发生什么Fn(当然这需要每晚)......
#![feature(fn_traits, unboxed_closures)]
struct MyFunction;
impl<T> FnOnce<(T,)> for MyFunction {
type Output = T;
extern "rust-call" fn call_once(self, (v,): (T,)) -> T { v }
}
Run Code Online (Sandbox Code Playgroud)
现在想象一下你的结构:
struct StructA<F>(F);
impl<F: FnOnce(T) -> T, T> StructA<F>{
fn foo(self) -> T { (self.0)() }
}
let s: StructA<MyFunction> = ...;
s.foo(); // What is `T`?
Run Code Online (Sandbox Code Playgroud)
虽然参考文献说:
如果参数在以下之一中至少出现一次,则通用参数会限制实现:
这是不准确的。引用RFC:
如果类型参数根据以下推理规则受到“约束”,则它们是合法的:
- ...
- 如果
<T0 as Trait<T1...Tn>>::U == V出现在 impl 谓词中,并且T0...Tn受到约束并且T0 as Trait<T1...Tn>不是 impl 特征引用,则V受到约束。
也就是说,特征中出现的所有类型参数都应该受到约束,而不仅仅是其中之一。
相关: https: //github.com/rust-lang/rust/issues/25041。
| 归档时间: |
|
| 查看次数: |
256 次 |
| 最近记录: |