首页 > 解决方案 > 在另一种支持泛型的类型中使用 impl Trait

问题描述

我有以下公共特征

pub trait UIElement {
    /// Is this UIElement a child of any other UIElement?
    fn parent<T: UIElement>(&self) -> Option<T>;

    /// Where to position
    /// TODO: Determine recursivly by checking the position of
    /// its parents.
    fn area(&self) -> Area;

    /// Should this UIElement be visible?
    fn visible(&self) -> bool;

    /// Is this UIElement actually visible?
    /// A UIElement can only be visible, if the parent (e.g. a container)
    /// is also visible (and its parent and so on resursively).
    fn actually_visible(&self) -> bool {
        let parent_visible: bool = if let Some(parent) = self.parent() {
            parent.actually_visible()
        }else { true };

        parent_visible && self.visible()
    }
}

actually_visible()应该只返回 true,如果它本身是visible()并且前一个父对象是actually_visible()递归的。

当我创建该parent()方法时,我不能只使用Option<impl UIElement>Option<Self>(如果我没记错的话,Self 可能只适用于实际结构)作为返回类型。然而,我选择的语法基本上应该是Option<impl UIElement>.
使用它,编译器至少不再抱怨了。(虽然我还是有点恼火,但这不是这个问题的重点)。

现在的问题在于actually_visible().
当试图从中解决时,它无法推断出父母的类型actually_visible()

error[E0282]: type annotations needed
error[E0282]: type annotations needed
  --> src/ui.rs:40:13
   |
40 |             parent.actually_visible()
   |             ^^^^^^ cannot infer type
   |
   = note: type must be known at this point
help: consider specifying the type argument in the method call
   |
39 |         let parent_visible: bool = if let Some(parent) = self.parent::<T>() {
   |                                                                     ^^^^^

我怎样才能使这项工作?

PS:我已经研究了其他一些解决方案。虽然有没有办法表明 impl 特征类型也实现了其他特征?有一个非常相似的问题,这似乎对我不起作用。也许 rust 编译器有递归问题/限制?

标签: rust

解决方案


看起来您尝试使用泛型的唯一地方是这一行:

fn parent<T: UIElement>(&self) -> Option<T>;

这不是必需的,因为 Rust 已经知道正在操作的实际类型将是一个更具体的实现类型,UIElement因此这里似乎不需要使用泛型。

话虽如此,因为 Rust 不提前知道将要使用的实际对象的大小(因为它可能会有所不同),所以您需要依靠堆来保存这些对象。

因此,我将返回类型中的T替换为

Box<dyn UIElement>

像这样...

fn parent(&self) -> Option<Box<dyn UIElement>>;

添加区域定义后

pub struct Area
{

}

我能够编译您的代码(尽管您用于“区域”的内容取决于您)。


推荐阅读