微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Rc 上实现 Trait 不会解析为 Rc<dyn Trait>,以下实现被发现 <Rc<T> as Trait>

如何解决在 Rc 上实现 Trait 不会解析为 Rc<dyn Trait>,以下实现被发现 <Rc<T> as Trait>

我试图在 Rc 周围包装一个 DST,目的是克隆它并从代码的各个部分访问它,但在编译时出现以下错误

这是错误 (playground) 的最小可重现示例:

use std::rc::Rc;

trait Trait<'a> {
    fn return_hello(&self) -> &'a str;
}

impl<'a,F> Trait<'a> for F
where
    F: Fn() -> &'a str
{
    fn return_hello(&self) -> &'a str {
        self()
    }
}

impl<'a,T> Trait<'a> for Rc<T> 
where
    T: Trait<'a>
{
    fn return_hello(&self) -> &'a str {
        (**self).return_hello()
    } 
}

fn caller<'a,T>(t: T) 
where
    T: Trait<'a>
{
    print!("{}\n",t.return_hello());
}

fn main() {
    fn test1<'a>() -> &'a str {
        "Hello from function"
    }
    let test2 = move || "hello from closure";
    
    fn f<'a>() -> &'a str {
        "Hello from Rc"
    }
    let test3: Rc<dyn Trait<'_>> = Rc::new(f);

    caller(test1);
    caller(test2);
    caller(test3);
}

给出:

error[E0277]: the trait bound `Rc<dyn Trait<'_>>: Trait<'_>` is not satisfied
  --> src/main.rs:45:12
   |
25 | fn caller<'a,T>(t: T) 
   |    ------ required by a bound in this
26 | where
27 |     T: Trait<'a>
   |        --------- required by this bound in `caller`
...
45 |     caller(test3);
   |            ^^^^^ the trait `Trait<'_>` is not implemented for `Rc<dyn Trait<'_>>`
   |
   = help: the following implementations were found:
             <Rc<T> as Trait<'a>>

解决方法

你的 impl for Rc<T> 有一个隐含的要求 T: Sized,就像你写的:

impl<'a,T> Trait<'a> for Rc<T> 
where
    T: Trait<'a> + Sized //The latter is implicit

但是当您想将其应用于 Rc<dyn Trait<'a>> 时,类型 Tdyn Trait<'a>,即不是 Sized,因此它不适用。

解决方案是添加 + ?Sized 以放宽该要求 (playground)

impl<'a,T> Trait<'a> for Rc<T> 
where
    T: Trait<'a> + ?Sized

既然您已经开始使用它,您也可以将其添加到另一个 impl 中:

impl<'a,F> Trait<'a> for F
where
    F: Fn() -> &'a str + ?Sized

所以它也适用于 dyn Fn() -> &'a str

,

Rc<T>Trait 实现中,T 具有 Sized (source) 的隐式边界,因此,{{ 1}} 只会解析为 Rc<T> 类型。只需告诉Sized“可能无法调整大小”即可解决问题,因此添加T

?Sized

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。