我有这个工作代码:
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
,但它不一定是R
,例如它可以T: Renderable
。我想避免使用dyn Renderable
的任何解决方案,以保持静态调度。
T: Renderable
类型在实例化时是已知的Layer
并且不会更改。
TL;DR:这是不可能的(至少没有可变参数泛型*(
-
目前
Layer
结构需要2
通用参数:R
和'a
。 -
假设我们找到了适合
/* ? */
的类型。让我们将其命名为T0
. -
然后
Layer
结构将需要3
泛型参数:T0
、R
和'a
。 -
然后,您必须为
parent
字段再提供一个通用参数。让我们将其命名为T1
. -
然后
Layer
结构将需要4
泛型参数:T1
、T0
、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
结构的一部分。这导致为Layer
引入新的通用参数。这会为parent
字段引入其他泛型参数。
为了分解递归,parent
的其他泛型参数不应是Layer
定义的一部分。如果参数不是Layer
定义的一部分,那么我们无法在编译时计算Layer
大小。解决方式是&dyn
或Box
。
*另一种可能的解决方案是可变参数泛型,但看起来我们至少在未来几个月甚至几年内都不会拥有它。