【发布时间】:2019-05-09 19:43:15
【问题描述】:
The Rustonomicon的当前版本有这个示例代码:
use std::mem;
pub struct IterMut<'a, T: 'a>(&'a mut [T]);
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let slice = mem::replace(&mut self.0, &mut []);
if slice.is_empty() {
return None;
}
let (l, r) = slice.split_at_mut(1);
self.0 = r;
l.get_mut(0)
}
}
我特别对这一行感到困惑:
let slice = mem::replace(&mut self.0, &mut []);
// ^^^^^^^
这个借位如何检查?如果这是一个不可变借用,RFC 1414 表示[] 右值应该具有'static 生命周期,因此不可变借用将借用检查,但示例显示可变借用!似乎必须发生以下两件事之一:
-
[]中的任何一个都是临时的(以便可以可变地使用),在这种情况下,它不会有'static的生命周期,也不应该借用检查; - 或者
[]具有'static生命周期,因此不可能进行可变借用(因为我们不保证在借用时独占访问),并且不应进行借用检查。
我错过了什么?
相关:
-
Why can I return a reference to a local literal but not a variable?
这个问题的重点是不可变引用;这个问题是关于可变的引用。
-
Why is it legal to borrow a temporary?
这个问题的重点是在函数内部获取引用;这个问题是关于返回参考。
【问题讨论】:
-
好的,所以
[]是一个文字,因此是静态分配的,我猜这可能是其中的一部分。但是,为什么我们能够对通用结构进行可变引用呢?可变引用应该是排他的...... -
答案的另一部分似乎是零大小的类型允许可变引用。引用rfc1414:“...别名可变引用仅对零大小类型是安全的(因为您永远不会取消引用它们的指针)。”
-
@Shepmaster 我认为这是一个与原始问题不同的问题,我已重新编写以使其更清楚。我不确定我上面的 cmets 是否准确地反映了当前状态(我从 rfc1414 引用的文本表明可以在该 RFC 的扩展中改进对零大小类型的处理),因此这可能值得更权威的回应。
标签: rust borrow-checker