这个问题是在泛型关联类型在Rust中可用之前提出的,尽管它们是被提出和开发的。
我的理解是,特征泛型和关联类型在它们可以绑定到结构的类型数量上有所不同。
struct Struct;
trait Generic<G> {
fn generic(&self, generic: G);
}
impl<G> Generic<G> for Struct {
fn generic(&self, _: G) {}
}
fn main() {
Struct.generic(1);
Struct.generic("a");
}
关联类型仅绑定1个类型:
struct Struct;
trait Associated {
type Associated;
fn associated(&self, associated: Self::Associated);
}
impl Associated for Struct {
type Associated = u32;
fn associated(&self, _: Self::Associated) {}
}
fn main() {
Struct.associated(1);
// Struct.associated("a"); // `expected u32, found reference`
}
泛型关联类型是这两种类型的混合。它们绑定到一个类型,正好有一个关联的生成器,而生成器又可以关联任何数量的类型。那么前面示例中的generic
和这个泛型关联类型有什么区别呢?
struct Struct;
trait GenericAssociated {
type GenericAssociated;
fn associated(&self, associated: Self::GenericAssociated);
}
impl<G> GenericAssociated for Struct {
type GenericAssociated = G;
fn associated(&self, _: Self::GenericAssociated) {}
}
我们再来看看你最后一个例子(被我缩短了):
trait GenericAssociated {
type GenericAssociated;
}
impl<G> GenericAssociated for Struct {
type GenericAssociated = G;
}
这不具有泛型关联类型的特性!您只是在impl
块上有一个泛型类型,您将该泛型类型分配给关联的类型。嗯,好吧,我知道混乱是从哪里来的了。
您的示例错误为“类型参数g
不受impl特征、self类型或谓词的约束”。当《服贸总协定》实施时,这一点不会改变,因为,再一次,这与《服贸总协定》无关。
trait Associated {
type Associated<T>; // <-- note the `<T>`! The type itself is
// generic over another type!
// Here we can use our GAT with different concrete types
fn user_choosen<X>(&self, v: X) -> Self::Associated<X>;
fn fixed(&self, b: bool) -> Self::Associated<bool>;
}
impl Associated for Struct {
// When assigning a type, we can use that generic parameter `T`. So in fact,
// we are only assigning a type constructor.
type Associated<T> = Option<T>;
fn user_choosen<X>(&self, v: X) -> Self::Associated<X> {
Some(x)
}
fn fixed(&self, b: bool) -> Self::Associated<bool> {
Some(b)
}
}
fn main() {
Struct.user_choosen(1); // results in `Option<i32>`
Struct.user_choosen("a"); // results in `Option<&str>`
Struct.fixed(true); // results in `Option<bool>`
Struct.fixed(1); // error
}
流式迭代器的GAT版本如下所示:
trait Iterator {
type Item<'a>;
fn next(&self) -> Option<Self::Item<'_>>;
}
在current Rust中,我们可以将lifetime参数放在trait上,而不是相关的类型:
trait Iterator<'a> {
type Item;
fn next(&'a self) -> Option<Self::Item>;
}
到目前为止还不错:所有迭代器都可以像以前一样实现这个特性。但如果我们要用呢?
fn count<I: Iterator<'???>>(it: I) -> usize {
let mut count = 0;
while let Some(_) = it.next() {
count += 1;
}
count
}
fn count<I: Iterator>(it: I) { ... }
它会奏效的。因为“具体生存期的应用”只有在我们调用next
时才会发生。
如果您对更多信息感兴趣,可以看看我的博客文章“在没有GATS的情况下解决Generalized Streaming Iterator Problem”,我尝试在traits上使用泛型类型来解决GATS的不足。而且(剧透):通常都不起作用。
类型和泛型 类型系统的首要目的是检测程序错误。类型系统有效的提供了一个静态检测的有限形式,允许我们代码中明确某种类型的变量并且编译器可以验证。类型系统当然也提供了其他好处,但错误检测是他存在的理由(Raison d’Être) 我们使用类型系统应当反映这一目标,但我们必须考虑到读者(译注:读你代码的人):明智地使用类型可以增加清晰度,而过份聪明只会迷乱。 Scala的强大类型系统是学术探索和实践共
如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。 背景: 我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如: 或
null 在编写代码时,什么时候应该选择关联类型而不是泛型类型参数,什么时候应该做相反的操作?
在研究泛型时,我注意到泛型方法和泛型类型(类或接口)在类型引入语法上的一个差异使我感到困惑。 泛型方法的语法为 文件上说 为了彼此保持一致,我希望方法语法为 ,或者类型语法(for class)为,但事实显然并非如此。 为什么一个要介绍在前,另一个要介绍在后? 我主要以的形式使用泛型,并认为可能看起来很奇怪,但这是一个主观的参数,此外对于方法也是这样。您可以调用,类似于 在寻找技术解释时,我想在指
泛型类型 除了反省函数, Swift允许你定义自己的泛型类型. 它们是可以用于任意类型的自定义类、结构体、枚举, 和Array、Dictionary方式类型. 1. 定义泛型类型 定义一个普通的结构体 struct IntStack { var items = [Int]() mutating func push(_ item: Int) { items.appen
我是Spring的新手,我正在尝试自动连接一个通用DAO。不幸的是,我遇到了一个错误。我试图根据它搜索信息,但大多数解决方案都声明使用@Qualifier注释,我认为这与我想要实现的目标背道而驰。 所以下面的一些代码(我将摆脱类参数,一旦我处理当前问题): 道 服务 和下面抛出的错误: