类型`A`没有实现特性`A`

5

我正在尝试使用一个具有以闭包为参数的函数的特质,并将其用于特质对象。

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

struct B {
    a: Box<A>
}

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

这段代码会产生以下错误:

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)

1个回答

7
问题在于方法f是泛型的,因此不具备对象安全性,无法在特质对象上调用。您需要强制其用户传递带有封装闭包的指针。
trait A {
    fn f(&self, p: Box<Fn() -> ()>);
}

我不明白为什么Rust会允许使用Box<A>,我本来期望会出现错误。而且这个错误的提示信息真的很误导人。我想提交一个关于这个问题的bug报告。

另外,你可以使用有界泛型取代特质对象,虽然这并不总是可行。


1
在 Rust 中,Box<TraitA> 不是合法的吗? - Daniel Fath
1
@DanielFath:关键是Box<A>几乎没什么用,因为A不是对象安全的——你实际上不能任何事情。 - Chris Morgan
@ChrisMorgan 很有趣。你能给我指一些更多关于什么是对象安全以及什么不是对象安全的资源吗? - Daniel Fath
1
这是一篇关于该主题的博客文章,作者是huon:http://huonw.github.io/blog/2015/01/object-safety/ - bluss
1
请注意,如果您想使用堆栈而不是堆,则实际上可以使用引用(&)而不是 Box。即 fn f(&self, p: &Fn() -> ());。显然,尽管没有使用 Box,但仍称其为“boxed closure”。在这种情况下,“boxed”只是指它是指针类型。 - Cam Jackson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接