gpt4 book ai didi

rust - 引用参数化函数的结构的生命周期错误

转载 作者:行者123 更新时间:2023-11-29 07:48:30 25 4
gpt4 key购买 nike

如果我编写下面的代码,我会得到错误[E0309]:参数类型“T”可能不够长

struct Function<T> {
f: fn() -> T,
}

struct FunctionRef<'f, T> {
f: &'f Function<T>,
}

这修复了错误:

struct FunctionRef<'f, T: 'f> {
f: &'f Function<T>,
}

但是,据我所知,T 不受生命周期 'f 的约束。事实上,T 是在运行类型为fn () -> T 的函数时创建的新对象。

我哪里遗漏了什么?

最佳答案

简短回答:您需要 T: 'f 因为 T 可能包含包含引用的字段并且 fn() -> T 是协变的在 T 上。

简化事情可能有助于理解...

暂时将 fn() -> T 替换为 T,因为对我来说,解释它在生命周期中发生的事情更简单。请参阅下面的说明,为什么使用此替换不会更改与生命周期相关的错误。

struct Function<T> {
f: T,
}

struct FunctionRef<'f, T> {
f: &'f Function<T>,
}

这会导致相同的错误[E0309]:参数类型“T”可能生命周期不够长错误。

FunctionRef 实例不能比它在 f 字段中持有的引用长:在尖括号内声明一个通用生命周期参数 'f 然后使用 'f 作为注解在结构体内。另见 book .

但是 FunctionRef::f 依赖于类型参数 T。显式约束 T: 'f 保证 T 实例不会超过 TFunctionRef 持有的引用不会超过 FunctionRef::f

如果用特定的 Foo 类型替换通用的 T 有助于理解:

struct Foo<'a> {
n: &'a i32,
}

struct FunctionRef<'f, 'a: 'f> {
f: &'f Foo<'a>,
}

您需要限制生命周期 'a 的有效期至少与 'f 生命周期一样长,否则将违反内存安全规则。

注意事项

我考虑过 f: T 等同于 f: fn() -> T 的情况,因为这种类型构造函数在 T 上是协变的.

要理解 fn() -> TT 上是协变的,考虑这个结构:

struct Foo<'a> {
v: &'a i32
}

在这种情况下,为 v 分配一个生命周期“大于”'a 的值是安全的,例如:

let ref_value: &'static i32 =  &100;
let foo = Foo { v: ref_value};

现在同样适用于以下结构:

struct Function<'a> {
f: fn() -> &'a i32
}

字段 f 需要一个返回 &i32 的函数,该函数比 'a 还长。

在这种情况下,传递一个返回具有“更大”生命周期的 &i32 的函数是安全的,例如:

fn my_f() -> &'static i32 {
&100
}

fn main() {
let foo = Function { f: my_f};
}

这背后有相当多的类型理论,see the nomicom以获得详细的解释。

关于rust - 引用参数化函数的结构的生命周期错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53386717/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com