简体   繁体   English

为什么这个一揽子特征实现的类型参数不被认为是受约束的?

[英]Why is the type parameter of this blanket trait implementation not considered to be constrained?

I'm trying to understand how type constraints interact with associated types, and I've hit upon this case that I don't understand.我试图了解类型约束如何与关联类型交互,并且遇到了我不理解的这种情况。 I've read the RFC on unconstrained types in generic impl s, but I can't see how this fits into the list of disallowed things.我已经阅读了关于泛型impl中不受约束类型的 RFC,但我看不出这如何适合被禁止的事物列表。 Intuitively, I would expect that for any type implementing Baz<T> , this code would specify exactly one unambiguous impl of Foo .直观地说,我希望对于任何实现Baz<T>的类型,此代码将准确指定Foo的一个明确impl Am I wrong about that, or can the compiler just not make that leap of logic?我错了,还是编译器不能实现逻辑上的飞跃? If not, why not?如果不是,为什么不呢?

trait Foo {
    type Bar;
    fn foo(&self) -> Self::Bar;
}

trait Baz<T> {
    fn foo(&self) -> T;
}

impl<T, TBaz> Foo for TBaz
where
  TBaz: Baz<T>
{
    type Bar = T;
    fn foo(&self) -> Self::Bar {
        Baz::<T>::foo(self)
    }
}

( Playground ) 游乐场

error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
  --> src/lib.rs:10:6
   |
10 | impl<T, TBaz> Foo for TBaz
   |      ^ unconstrained type parameter

For more information about this error, try `rustc --explain E0207`.

Intuitively, you are wrong because there is not one unambiguous impl .直觉上,你错了,因为没有一个明确的impl Assume a type SomeType that implements both Baz<i32> and Baz<f32> .假设一个实现 Baz< SomeType Baz<i32>Baz<f32>的类型 SomeType 。 What impl will we choose?我们会选择什么impl? What will be the value of the associated type Bar - i32 or f32 ?关联类型Bar - i32f32的值是多少?

Formally (and from the compiler point of view), you are wrong because you are breaking the rules :正式地(从编译器的角度来看),你错了,因为你违反了规则

Generic parameters constrain an implementation if the parameter appears at least once in one of:如果参数在以下之一中至少出现一次,则通用参数会限制实现:

  • The implemented trait, if it has one实现的特征,如果它有一个
  • The implementing type实现类型
  • As an associated type in the bounds of a type that contains another parameter that constrains the implementation作为包含约束实现的另一个参数的类型边界中的关联类型

Type and const parameters must always constrain the implementation.类型和 const 参数必须始终约束实现。 Lifetimes must constrain the implementation if the lifetime is used in an associated type.如果生命周期用于关联类型,则生命周期必须约束实现。

T appears neither in the implemented trait ( Foo ), nor in the implementing type ( TBaz ) or as an associated type. T既不出现在已实现的特征 ( Foo ) 中,也不出现在实现类型 ( TBaz ) 中或作为关联类型。 And it is a type parameter.它是一个类型参数。

I think your intuition failure was by the assumption that TBaz will implement Baz only for one type, probably by a generic implementation impl<T> Baz<T> for TBaz<T> .我认为您的直觉失败是假设TBaz将只为一种类型实现Baz ,可能是通过通用实现impl<T> Baz<T> for TBaz<T> But this is not enforced by the language.但这不是由语言强制执行的。 There is a mechanism that enforces that - associated types.有一种机制可以强制执行 - 关联类型。 If T was an associated type of Baz it was fine.如果TBaz的关联类型,那很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM