为什么生命周期检查在 Vec::as_slice 和数组的强制之间不同?
Why lifetime check differs between Vec::as_slice and array's coercence?
最小代码:
fn foo() {
let vector = vec![1u8, 2u8];
let a = &vector.as_slice()[0];
drop(vector);
let b = a;
}
fn bar() {
let array = [1u8, 2u8];
let a = &array[0];
drop(array);
let b = a;
}
编译上述代码时,foo
编译不通过,bar
可以编译
在函数foo
中,a
借用了vector
,所以我删除vector
后,就无法再访问a
了。
不过,我觉得bar
的情况也是一样的,但是bar
可以顺利通过编译。不知道为什么。
这并不特定于向量和数组。
一旦 Rust 可以证明一个值是编译时已知的常量,它就会认为它具有静态生命周期(并且在这种情况下 drop 没有任何影响,因为该值将永远存在)。
参见 。
我用一个放在变量中的简单常量 (binding) 和盒装版本扩展了您的示例;这显示了与您在向量和数组之间注意到的完全相同的区别(平凡常量与动态分配的值)。
fn test_vec() {
let src = vec![10u8, 20u8];
let a = &src[0];
// drop(src); // rejected by compiler
let b = a;
println!("{:?}", b);
}
fn test_array() {
let src = [10u8, 20u8];
let a = &src[0];
drop(src);
let b = a;
println!("{:?}", b);
}
fn test_box() {
let src = Box::new(10u8);
let a = &src;
// drop(src); // rejected by compiler
let b = a;
println!("{:?}", b);
}
fn test_var() {
let src = 10u8;
let a = &src;
drop(src);
let b = a;
println!("{:?}", b);
}
fn main() {
test_vec();
test_array();
test_box();
test_var();
}
不可变数组文字具有静态生命周期。在这种情况下,删除局部变量 array
并没有真正做任何事情——当二进制文件被加载时,数据被映射到内存中,并且它将在程序的运行期间保留在那里,所以引用仍然有效。你不能再通过 array
变量访问内存了。
矢量情况非常不同。创建一个新的vector会在运行时在堆上动态分配内存,drop()
会再次释放那块内存,所以引用就失效了。
最小代码:
fn foo() {
let vector = vec![1u8, 2u8];
let a = &vector.as_slice()[0];
drop(vector);
let b = a;
}
fn bar() {
let array = [1u8, 2u8];
let a = &array[0];
drop(array);
let b = a;
}
编译上述代码时,foo
编译不通过,bar
可以编译
在函数foo
中,a
借用了vector
,所以我删除vector
后,就无法再访问a
了。
不过,我觉得bar
的情况也是一样的,但是bar
可以顺利通过编译。不知道为什么。
这并不特定于向量和数组。
一旦 Rust 可以证明一个值是编译时已知的常量,它就会认为它具有静态生命周期(并且在这种情况下 drop 没有任何影响,因为该值将永远存在)。
参见
我用一个放在变量中的简单常量 (binding) 和盒装版本扩展了您的示例;这显示了与您在向量和数组之间注意到的完全相同的区别(平凡常量与动态分配的值)。
fn test_vec() {
let src = vec![10u8, 20u8];
let a = &src[0];
// drop(src); // rejected by compiler
let b = a;
println!("{:?}", b);
}
fn test_array() {
let src = [10u8, 20u8];
let a = &src[0];
drop(src);
let b = a;
println!("{:?}", b);
}
fn test_box() {
let src = Box::new(10u8);
let a = &src;
// drop(src); // rejected by compiler
let b = a;
println!("{:?}", b);
}
fn test_var() {
let src = 10u8;
let a = &src;
drop(src);
let b = a;
println!("{:?}", b);
}
fn main() {
test_vec();
test_array();
test_box();
test_var();
}
不可变数组文字具有静态生命周期。在这种情况下,删除局部变量 array
并没有真正做任何事情——当二进制文件被加载时,数据被映射到内存中,并且它将在程序的运行期间保留在那里,所以引用仍然有效。你不能再通过 array
变量访问内存了。
矢量情况非常不同。创建一个新的vector会在运行时在堆上动态分配内存,drop()
会再次释放那块内存,所以引用就失效了。