我有一个小库,它导出一个带有生命周期注释的结构。现在我尝试从另一个程序中使用它,但似乎我现在也需要在那里使用生命周期注释。基本上我这样做:
// in my lib
struct Foo<'a> {
baz: &'a str
}
// another program
struct Bar {
foo: Foo
}
Run Code Online (Sandbox Code Playgroud)
其中说Bar必须为 定义一个生命周期Foo:
<anon>:6:10: 6:13 error: wrong number of lifetime parameters: expected 1, found 0 [E0107]
<anon>:6 foo: Foo
^~~
Run Code Online (Sandbox Code Playgroud)
这很容易解决:
struct Bar<'a> {
foo: Foo<'a>
}
Run Code Online (Sandbox Code Playgroud)
但这意味着我现在还必须为使用 的任何东西定义生命周期Bar,等等,对吗?如果这是真的,除了使用不需要显式生命周期的类型之外,还有什么方法可以解决这个问题?或者像这样使用拥有的类型会更好String吗?
我使用了一些背景知识,&str因为我必须调用一个需要作为参数的函数。虽然转换它们没有问题,但它实际上是一个Vec<(&str, &str)>,所以我的想法是首先通过使用正确的类型来摆脱转换。我有一种感觉,那是一个错误的决定,但我知道什么...... :)
是的,目前没有办法绕过显式生命周期的冒泡。考虑它的方法是Foo需要明确与哪个生命周期相关联,因为该baz字段取决于它,因此例如,如果您尝试使生命周期Foo长于数据baz引用,编译器就会知道阻止您到,或者这样您就可以拥有返回“与 baz 存在的时间一样长”的引用的方法。如果你然后嵌入Foo到Bar, 现在Bar需要一个明确的生命周期,因为Foo取决于它。
如果Foo是“拥有”字符串,这意味着如果 aFoo应该能够独立于任何可能的生命周期(例如范围)独立存在,那么它确实应该是 a String。从 aString转换为切片的成本非常低,因为切片只是现有数据的视图。
但是,如果您总是Foo基于与范围相关的现有数据(例如,传递给包含Foo实例的函数的字符串切片等)进行构建,并且Foo实例不需要超出该范围现有数据,那么如果您String将其设为 a String,则必须将切片转换为 a (与反向相比相对昂贵),然后在使用时将其转换回切片,在这种情况下,您应该保留它作为切片。您当然不应该仅仅为了避免输入显式生命周期而招致这种性能损失。
您会发现具有显式生命周期的类型非常普遍,因此虽然乍一看确实令人担忧,但您会习惯的。
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |