Rust 当我添加生存期时,有没有办法避免向所有下游结构添加生存期?

Rust 当我添加生存期时,有没有办法避免向所有下游结构添加生存期?,rust,lifetime,Rust,Lifetime,我有一个结构: struct C { field: Box<Fn()> } struct D(C) struct E(C) struct F(D) 然后对于D,E,F,我还必须提供寿命参数: struct D<'a>(c<'a>) struct E<'a>(C<'a>) struct F<'a>(C<'a>) struct D) 结构(E) 结构(F) 想象一下D,E,F有许多impl功能。。。现

我有一个结构:

struct C {
    field: Box<Fn()>
}

struct D(C)
struct E(C)
struct F(D)
然后对于
D
E
F
,我还必须提供寿命参数:

struct D<'a>(c<'a>)
struct E<'a>(C<'a>)
struct F<'a>(C<'a>)
struct D)
结构(E)
结构(F)
想象一下
D
E
F
有许多
impl
功能。。。现在,代码需要进行大量更改,才能在很多地方添加生存期参数


有没有办法避免这样做?
C
的生存期参数不能是静态的,因为我也有一些本地定义的闭包。

有一种非常简单的方法可以避免这种情况:只需对常规函数使用
Box

Rust有两种类型的抽象函数:

  • fn()
    表示“简单”函数
  • Fn()
    对函数和闭包进行抽象
因此,使用
可以同时实现这两种功能

当然,这里有一个内存分配,这对于“裸”函数是不必要的。您可能会发现这种权衡是可以接受的,而不必重构整个代码

如果您打算避免内存分配,您可能需要研究“如何避免添加一个生命周期”的问题,这可能解决了您的问题,但不是您的问题:

当我添加生存期时,有没有办法避免向所有下游结构添加生存期


不,不可能。生存期注释是另一种泛型类型,您可以使用它参数化您的类型。所有使用该类型的人都必须知道它被参数化的具体生命周期。生命周期的一个重要原因就是因为这个——为了有一个安全的系统,编译器(和您!)必须知道结构包含对可能超出范围的内容的引用。发生这种情况时,引用不再有效。

常规函数的大小为零。装箱一个零大小的类型根本不会执行任何分配(分配器只会为指针返回
1
。@FrancisGagné:你确定吗?当然,运行时需要一个指向函数的指针来知道调用哪个函数…@MatthieuM.:正常函数都有自己的类型:这种类型的大小为零。但是,此类型也可以强制转换为函数指针类型,该类型的大小与常规指针相同。但是如果使用不同的函数类型,则
Box
不会执行堆分配:
Fn
的vtable将分派到正确的函数。@FrancisGagné:啊,我明白了,所以指向函数的指针在v表中实现。那很聪明。
struct D<'a>(c<'a>)
struct E<'a>(C<'a>)
struct F<'a>(C<'a>)