jts*_*jts 6 arrays function lifetime rust
我正在学习 Rust,并正在通过函数测试一些数组复制。我确信有内置的 Rust 函数可以复制/克隆数组信息,但我认为个人实现是一个好主意,可以帮助我理解通过函数传递引用。
fn copy_str_arr_original (a1: [&str; 60], a2: &mut [&str; 60]) {
// copy 1 into 2
for i in 0..60 {
a2[i] = a1[i];
} // change is reflected in a2 as it is passed as &mut
}
Run Code Online (Sandbox Code Playgroud)
these two types are declared with different lifetimes...然而,这引发了类型本身的错误&str。经过进一步的研究,我尝试声明我自己的一生并将它们分配给它,这解决了问题!
fn copy_str_arr_fix<'a> (a1: [&'a str; 60], a2: &mut [&'a str; 60]) {
// copy 1 into 2
for i in 0..60 {
a2[i] = a1[i];
} // change is reflected in a2 as it is passed as &mut
}
Run Code Online (Sandbox Code Playgroud)
但为什么会这样呢?为什么需要为数组中的值类型而不是参数本身分配生命周期?换句话说,为什么这根本不起作用?
fn copy_str_arr_bad<'a> (a1: &'a [&str; 60], a2: &'a mut [&str; 60]) {
// does not work... ^-----------------------^-------- different lifetimes
for i in 0..60 {
a2[i] = a1[i];
}
}
Run Code Online (Sandbox Code Playgroud)
我仍在努力了解生命周期在更复杂的对象(例如数组和结构)的上下文中如何工作,因此任何解释将不胜感激!
该错误消息有点令人困惑,因为它指的是根据生命周期省略规则生成的生命周期。就您而言,终身省略意味着:
fn copy_str_arr_original(a1: [&str; 60], a2: &mut [&str; 60])
Run Code Online (Sandbox Code Playgroud)
是语法糖:
fn copy_str_arr_original<'a1, 'a2_mut, 'a2>(a1: [&'a1 str; 60], a2: &'a2_mut mut [&'a2 str; 60])
Run Code Online (Sandbox Code Playgroud)
换句话说,我们有三个完全不相关的生命周期。“不相关”意味着调用者可以选择与他们关联的对象的生存时间。例如, in 中的字符串a2可能是静态的并一直存在,直到程序结束,而 in 中的字符串a1可能在返回后立即被删除copy_str_arr_original()。或者反过来。如果这种程度的自由看起来可能会引起问题,那么您就走在正确的道路上,因为借用检查员同意您的观点。
请注意,有点违反直觉,'a2_mut生命周期的长度完全无关,它可以根据调用者的喜好长或短。我们的函数已收到引用,因此可以在函数作用域内使用它。生命周期告诉我们它在函数范围之外'a2_mut还能存活多久,而我们只是不关心它。
'a1又'a2是另一回事了。a1由于我们正在从to复制引用a2,因此我们实际上将内部(类型为)的引用转换为存储在(即)中的引用类型:a1&'a1 stra2&'a2 str
a2[i] = a1[i]; // implicitly casts &'a1 str to &'a2 str
Run Code Online (Sandbox Code Playgroud)
为了使其有效,&'a1 str必须是的子类型&'a2 str。虽然 Rust 没有 C++ 意义上的类和子类,但它确实有涉及生命周期的子类型。从这个意义上说,如果 A 值的值保证至少与 B 的值一样长,则 A 是 B 的子类型。换句话说,'a1必须至少与 一样长'a2,这表示为'a1: 'a2。所以编译如下:
fn copy_str_arr<'a1: 'a2, 'a2, 'a2_mut>(a1: [&'a1 str; 60], a2: &'a2_mut mut [&'a2 str; 60]) {
for i in 0..60 {
a2[i] = a1[i];
}
}
Run Code Online (Sandbox Code Playgroud)
演员成功的另一种方法是只要求生命周期相同,就像您在copy_str_arr_fix(). (您还省略了'a2_mut生命周期,编译器将其正确解释为对不相关的匿名生命周期的请求。)
| 归档时间: |
|
| 查看次数: |
460 次 |
| 最近记录: |