如何将特征与使用特征的关联类型作为参数的超特征绑定? [英] How do I bound a trait with a supertrait that uses the trait's associated type as a parameter?

查看:42
本文介绍了如何将特征与使用特征的关联类型作为参数的超特征绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特征 Trait 和一个关联类型 Trait::Associated.我试图通过要求其关联类型可索引来限制特征,如下所示:

使用 std::ops::Index;pub trait Trait: Index{类型关联;}

然而,编译器抱怨关联类型不明确

<块引用>

error[E0223]: 模棱两可的关联类型-->src/main.rs:3:24|3 |pub trait Trait: Index{|^^^^^^^^^^^^^^^^^ 模棱两可的关联类型|= 注意:使用语法`::Associated` 指定类型

我也尝试将关联类型称为 Self::Associated,但随后编译器对类型和特征之间的循环引用提出抗议:

<块引用>

error[E0391]: 检测到循环依赖-->src/main.rs:3:1|3 |酒吧特质特质:索引{|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 循环引用|注意:当计算 `Trait` 的超特征时,循环开始......-->src/main.rs:3:1|3 |酒吧特质特质:索引{|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^= 注意:...这又需要计算 `Trait` 的超特征,完成循环.

最后,我还尝试为 Trait 显式实现 Index:

pub trait Trait {类型关联;}impl<T:特质>索引对于 T {类型输出= str;fn index(&self, associated: T::Associated) ->&'static str {sup"}}

不幸的是,它也失败了:

<块引用>

error[E0210]: 类型参数 `T` 必须用作某些本地类型的类型参数(例如 `MyStruct<T>`)-->src/main.rs:7:1|7 |impl<T:特质>索引对于 T {|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 类型参数`T`必须用作某些本地类型的类型参数|= 注意:只有在当前 crate 中定义的特征才能为类型参数实现

我是不是想在这里做一些不合理的事情?有没有办法实现类似的东西,而不必使用泛型?

游乐场.

解决方案

你很亲近,很亲近.

Trait 不假定其定义中对 Trait 的任何引用都指向当前类型.毕竟,您可能希望参考其他也实现了 Trait 的类型.

为了指定你想要一个特定的类型,你应该注意编译器的注释:使用 ::Associated,其中 Type 是当前类型.

在定义Trait 时,您如何引用它将被实例化的具体类型?你使用Self

解决办法是:

pub trait Trait: Index<::Associated>{类型关联;}

I have a trait Trait with an associated type Trait::Associated. I am trying to bound the trait by requiring that it be indexable by its associated type, as shown here:

use std::ops::Index;

pub trait Trait: Index<Trait::Associated> {
    type Associated;
}

However, the compiler complains that the associated type is ambiguous

error[E0223]: ambiguous associated type
 --> src/main.rs:3:24
  |
3 | pub trait Trait: Index<Trait::Associated> {
  |                        ^^^^^^^^^^^^^^^^^ ambiguous associated type
  |
  = note: specify the type using the syntax `<Type as Trait>::Associated`

I also tried referring to the associated type as Self::Associated, but then the compiler protests about a cyclic reference between the type and the trait:

error[E0391]: cyclic dependency detected
 --> src/main.rs:3:1
  |
3 | pub trait Trait: Index<Self::Associated> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic reference
  |
note: the cycle begins when computing the supertraits of `Trait`...
 --> src/main.rs:3:1
  |
3 | pub trait Trait: Index<Self::Associated> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which then again requires computing the supertraits of `Trait`, completing the cycle.

Finally, I also tried explicitly implementing Index for Trait:

pub trait Trait {
    type Associated;
}

impl<T: Trait> Index<T::Associated> for T {
    type Output = str;

    fn index(&self, associated: T::Associated) -> &'static str {
        "sup"
    }
}

Unfortunately that fails too:

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
 --> src/main.rs:7:1
  |
7 | impl<T: Trait> Index<T::Associated> for T {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
  |
  = note: only traits defined in the current crate can be implemented for a type parameter

Am I trying to do something unreasonable here? Is there a way of achieving something similar, without having to use generics?

Playground.

解决方案

You are close, very close.

The Trait does not assume that any reference to Trait in its definition refers to the current type. After all, you could wish to refer to other types also implementing Trait.

In order to specify that you want a specific type, you should heed the compilers note: use <Type as Trait>::Associated, where Type is the current type.

When defining the Trait, how do you refer to the concrete type for which it will be instantiated? You use Self!

The solution is:

pub trait Trait: Index<<Self as Trait>::Associated> {
    type Associated;
}

这篇关于如何将特征与使用特征的关联类型作为参数的超特征绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆