gpt4 book ai didi

rust - 为什么可以从函数返回对文字的可变引用?

转载 作者:行者123 更新时间:2023-12-03 11:23:47 26 4
gpt4 key购买 nike

当前版本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?

    这个问题的重点是在函数内部获取引用;这个问题是关于返回 一个引用。
  • 最佳答案

    TL;DR:空数组在编译器中是特殊情况,它是安全的,因为你永远不能解引用零长度数组的指针,所以不可能有可变别名。

    RFC 1414 ,右值静态提升,讨论将值提升到 static 的机制值。它有一个关于 mutable references 可能的扩展的部分(粗体我的):

    It would be possible to extend support to &'static mut references, as long as there is the additional constraint that the referenced type is zero sized.

    This again has precedence in the array reference constructor:

    // valid code today
    let y: &'static mut [u8] = &mut [];

    The rules would be similar:

    • If a mutable reference to a constexpr rvalue is taken. (&mut <constexpr>)
    • And the constexpr does not contain a UnsafeCell { ... } constructor.
    • And the constexpr does not contain a const fn call returning a type containing a UnsafeCell.
    • And the type of the rvalue is zero-sized.
    • Then instead of translating the value into a stack slot, translate it into a static memory location and give the resulting reference a 'static lifetime.

    The zero-sized restriction is there because aliasing mutable references are only safe for zero sized types (since you never dereference the pointer for them).



    由此,我们可以看出对空数组的可变引用目前在编译器中是特殊情况。在 Rust 1.39 中,所讨论的扩展尚未实现:
    struct Zero;

    fn example() -> &'static mut Zero {
    &mut Zero
    }

    error[E0515]: cannot return reference to temporary value
    --> src/lib.rs:4:5
    |
    4 | &mut Zero
    | ^^^^^----
    | | |
    | | temporary value created here
    | returns a reference to data owned by the current function

    虽然阵列版本确实有效:
    fn example() -> &'static mut [i32] {
    &mut []
    }

    也可以看看:
  • Why is it legal to borrow a temporary?
  • Why can I return a reference to a local literal but not a variable?
  • 关于rust - 为什么可以从函数返回对文字的可变引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56066534/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com