如何在不分配新盒子的情况下转换盒装参考的生命周期?
How to convert lifetime of boxed reference without allocating a new box?
上下文
Playground,有效:
fn get_owned_box_working<'a>(b: Box<&'a i32>) -> Box<&'static i32> {
Box::new(&42)
}
但这不是:
fn get_owned_box_broken<'a>(b: Box<&'a i32>) -> Box<&'static i32> {
*b = &42;
b
}
error[E0308]: mismatched types
--> src/lib.rs:3:5
|
3 | b
| ^ lifetime mismatch
|
= note: expected struct `Box<&'static i32>`
found struct `Box<&'a i32>`
note: the lifetime `'a` as defined here...
--> src/lib.rs:1:25
|
1 | fn get_owned_box_broken<'a>(b: Box<&'a i32>) -> Box<&'static i32> {
| ^^
= note: ...does not necessarily outlive the static lifetime
问题
- 当我改变它时,为什么编译器无法从
'a
-> 'static
更新现有框的生命周期?
- 有没有什么方法可以让它工作而无需创建新框的额外分配?
How come the compiler can't update the lifetime of the existing box from 'a
-> 'static
when I mutate it?
从编译器的角度来看,您无法将使用 'a
的值“更新”为使用 'static
。您正在分配给它,但类型保持不变。然后稍后您尝试从 Box<&'a i32>
转换为 Box<&'static i32>
,并且它正确地保释。
Is there some way to get this to work without the extra allocation from creating a new box?
是,但仅使用 unsafe
:Playground
fn get_owned_box_broken<'a>(s: Box<&'a i32>) -> Box<&'static i32> {
unsafe {
let s = Box::into_raw(s);
let s = s.cast::<&'static i32>();
s.write(&42);
Box::from_raw(s)
}
}
但是,如果您需要,请仔细考虑:您可能负担得起分配。
你不能那样做,因为生命周期是类型的一部分。
因此,当您分配 *b = &42;
时,您的左侧部分的类型为 &'a i32
,右侧部分的类型为 &'static i32
。可以将更大的生命周期强制为更小的生命周期,所以没关系。但是你的变量 b
仍然有生命周期参数 'a
的类型,它在赋值后没有改变。
当您从函数 return b 时,您尝试将 Box<&'a i32>
转换为 Box<&'static i32>
。由于 'static
大于 'a
,因此失败。
上下文
Playground,有效:
fn get_owned_box_working<'a>(b: Box<&'a i32>) -> Box<&'static i32> {
Box::new(&42)
}
但这不是:
fn get_owned_box_broken<'a>(b: Box<&'a i32>) -> Box<&'static i32> {
*b = &42;
b
}
error[E0308]: mismatched types
--> src/lib.rs:3:5
|
3 | b
| ^ lifetime mismatch
|
= note: expected struct `Box<&'static i32>`
found struct `Box<&'a i32>`
note: the lifetime `'a` as defined here...
--> src/lib.rs:1:25
|
1 | fn get_owned_box_broken<'a>(b: Box<&'a i32>) -> Box<&'static i32> {
| ^^
= note: ...does not necessarily outlive the static lifetime
问题
- 当我改变它时,为什么编译器无法从
'a
->'static
更新现有框的生命周期? - 有没有什么方法可以让它工作而无需创建新框的额外分配?
How come the compiler can't update the lifetime of the existing box from
'a
->'static
when I mutate it?
从编译器的角度来看,您无法将使用 'a
的值“更新”为使用 'static
。您正在分配给它,但类型保持不变。然后稍后您尝试从 Box<&'a i32>
转换为 Box<&'static i32>
,并且它正确地保释。
Is there some way to get this to work without the extra allocation from creating a new box?
是,但仅使用 unsafe
:Playground
fn get_owned_box_broken<'a>(s: Box<&'a i32>) -> Box<&'static i32> {
unsafe {
let s = Box::into_raw(s);
let s = s.cast::<&'static i32>();
s.write(&42);
Box::from_raw(s)
}
}
但是,如果您需要,请仔细考虑:您可能负担得起分配。
你不能那样做,因为生命周期是类型的一部分。
因此,当您分配 *b = &42;
时,您的左侧部分的类型为 &'a i32
,右侧部分的类型为 &'static i32
。可以将更大的生命周期强制为更小的生命周期,所以没关系。但是你的变量 b
仍然有生命周期参数 'a
的类型,它在赋值后没有改变。
当您从函数 return b 时,您尝试将 Box<&'a i32>
转换为 Box<&'static i32>
。由于 'static
大于 'a
,因此失败。