2

我有这个工作代码:

struct Layer<'a> {
    parent: Option<Box<Layer<'a>>>,
    value: Box<dyn Renderable + 'a>,
}

我想要一个使用静态调度的版本:

struct Layer<'a, R: Renderable> {
    parent: Option<&'a Layer<'a, /* ? */>>,
    value: R,
}

替换问号的类型实现Renderable,但不一定RT: Renderable例如可以。我想避免使用任何解决方案dyn Renderable来保持静态调度。

该类型T: Renderable在实例化时是已知的Layer并且不会改变。

4

1 回答 1

2

TL;DR:这是不可能的(至少没有可变参数泛型*)

  • 现在Layer结构需要2通用参数:R'a.

  • 假设我们找到了正确的类型/* ? */。让我们命名它T0

  • 然后Layer结构将需要3通用参数T0R'a

  • 然后您必须为parent字段提供一个更通用的参数。让我们命名它T1

  • 然后Layer结构将需要4通用参数:T1T0和。R'a

  • 然后您必须为parent字段提供一个更通用的参数。让我们命名它T2

  • <...>

  • 然后Layer结构将需要i+2通用参数:Ti, Ti-1, ... T1, T0,R'a.
  • 然后您必须为parent字段提供一个更通用的参数。让我们命名它Ti+1
  • 然后Layer结构将需要i+1+2通用参数:Ti+1, Ti, Ti-1, ... T1, T0,R'a.
  • <...>

最后,你有无限递归。字段的附加通用参数parent必须定义为Layer结构的一部分。这导致引入了一个新的泛型参数Layerparent这会为字段引入额外的通用参数。

为了打破递归,额外的泛型参数parent不应该是Layer定义的一部分。如果参数不是Layer定义的一部分,那么我们无法Layer在编译时计算大小。可能解决的方法是&dynBox

*另一种可能的解决方案是可变参数泛型,但看起来我们至少在接下来的几个月甚至几年内都不会拥有它。

于 2020-02-05T21:15:51.223 回答