【问题标题】:Reference to generic trait with asscociated type as struct field引用具有关联类型作为结构字段的泛型特征
【发布时间】:2020-01-03 12:11:53
【问题描述】:

我正在努力说服 Rust 接受对实例的引用,该实例实现了具有关联类型的通用特征作为结构字段的值。您能否提供一些线索,看看下面的代码有什么问题。

trait TraitA{}

trait TraitB{
    type As: TraitA;
}

struct StructA;

impl TraitA for StructA{}

struct StructB;

impl TraitB for StructB{
    type As = StructA;
}

struct StructC<'a> {
    r: &'a (dyn TraitB<As = (dyn TraitA)> + 'a),
}


fn main(){
    let x = StructB;
    let z = StructC {
        r: &x,
    };
}

Playground

【问题讨论】:

  • 我根据 Pavel Arnold 的评论简化了代码示例。

标签: rust


【解决方案1】:

关于发布的编译器错误

导致的问题是TCPtransport 没有实现 Transport&lt;.., Configuration=(dyn TransportConfiguration&lt;SyncReq&gt;&gt;, 相反,它实现 Transport&lt;.., Configuration=TcpTranportCfg&gt;,后面的不能转换成前者:

playground

可能的解决方案:添加新特征(基本上是去除关联的类型信息):

trait SyncReqTransport{
    ...
}

impl<T> SyncReqTransport<SyncReq> for T 
    where 
        T: Transport<SyncReq>, // I Removed other parameters for simplicity
        <T as Transport<SyncReq>>::Config: TransportConfiguration<SyncReq>
{
    ...
}

并将DAG 更改为

pub struct DAG<'a, T> {
    request_transport: &'a (dyn SyncReqTransport + 'a),
}

另一个问题

sr_transport 在堆栈上创建,稍后引用它从返回 它创建的函数,这是非法的。

【讨论】:

  • 感谢您的浏览。您的游乐场示例从 Rust 编译器产生不同的错误。我已对其进行了修改以返回与代码中相同的错误:playground。所以问题是为什么 Rust 编译器没有看到 StryctA 实现了 TraitA 并满足 r 的字段 StructC 的要求?
  • 您可以通过引用关联类型的方法获得特征。如果您可以执行此转换,那么您将被允许传递引用任何 trait 实现者而不是预期的具体类型。然后,在这个方法的实现中,调用任何特定于结构但不是 trait 的方法都是非法的。
猜你喜欢
  • 2022-11-23
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
  • 2018-02-11
  • 2020-03-02
  • 1970-01-01
相关资源
最近更新 更多