【问题标题】:The trait `A` is not implemented for the type `A`没有为类型“A”实现特征“A”
【发布时间】:2015-07-15 07:52:03
【问题描述】:

我正在尝试使用具有以闭包作为参数的函数的特征,然后在特征对象上使用它。

trait A {
    fn f<P>(&self, p: P) where P: Fn() -> ();
}

struct B {
    a: Box<A>
}

impl B {
    fn c(&self) {
        self.a.f(|| {});
    }
}

这个sn-p会产生如下错误:

the trait `A` is not implemented for the type `A` [E0277]

rustc 的版本是rustc 1.0.0-beta.3 (5241bf9c3 2015-04-25) (built 2015-04-25)

【问题讨论】:

    标签: rust traits


    【解决方案1】:

    问题在于方法f 不是对象安全的,因为它是通用的,因此不能在特征对象上调用它。您将不得不强制其用户通过盒装关闭:

    trait A {
        fn f(&self, p: Box<Fn() -> ()>);
    }
    

    我想知道为什么 Rust 首先允许Box&lt;A&gt;,我预计那里会出现错误。而这个特定的错误确实具有误导性。我会提交一个关于这个的错误。

    或者,您可以丢弃 trait 对象以支持常规的有界泛型,但这并不总是可行的。

    【讨论】:

    • Box&lt;TraitA&gt; 在 Rust 中不合法吗?
    • @DanielFath:关键是Box&lt;A&gt; 几乎没用,因为A 不是对象安全的——你实际上无法任何事情。
    • @ChrisMorgan 有趣。您能否指出更多关于对象安全的含义以及对象安全和不安全的资源?
    • 这里是 huon 关于该主题的博文:huonw.github.io/blog/2015/01/object-safety
    • 请注意,如果您想使用堆栈而不是堆,实际上可以使用引用 (&amp;) 而不是 Box。 IE。 fn f(&amp;self, p: &amp;Fn() -&gt; ());。显然这仍然被称为“盒装闭包”,尽管没有使用Box。在这种情况下,'boxed' 仅仅意味着它是一个指针类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2015-11-11
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    相关资源
    最近更新 更多