gpt4 book ai didi

rust - 为什么 Rust 不能在类型构造函数中将可变引用强制为不可变引用?

转载 作者:行者123 更新时间:2023-12-03 11:24:30 25 4
gpt4 key购买 nike

可以强制&mut T进入 &T但如果类型不匹配发生在类型构造函数中,则它不起作用。

playground

use ndarray::*; // 0.13.0

fn print(a: &ArrayView1<i32>) {
println!("{:?}", a);
}

pub fn test() {
let mut x = array![1i32, 2, 3];
print(&x.view_mut());
}

对于上面的代码,我收到以下错误:
  |
9 | print(&x.view_mut());
| ^^^^^^^^^^^^^ types differ in mutability
|
= note: expected reference `&ndarray::ArrayBase<ndarray::ViewRepr<&i32>, ndarray::dimension::dim::Dim<[usize; 1]>>`
found reference `&ndarray::ArrayBase<ndarray::ViewRepr<&mut i32>, ndarray::dimension::dim::Dim<[usize; 1]>>`

强制是安全的 &mut i32&i32那么为什么它不适用于这种情况呢?你能否提供一些例子说明它怎么可能适得其反?

最佳答案

一般来说,强制是不安全的Type<&mut T>进入 Type<&T> .

例如,考虑这个包装器类型,它是在没有任何不安全代码的情况下实现的,因此是合理的:

#[derive(Copy, Clone)]
struct Wrapper<T>(T);

impl<T: Deref> Deref for Wrapper<T> {
type Target = T::Target;
fn deref(&self) -> &T::Target { &self.0 }
}

impl<T: DerefMut> DerefMut for Wrapper<T> {
fn deref_mut(&mut self) -> &mut T::Target { &mut self.0 }
}

此类型具有 &Wrapper<&T> 的属性自动取消对 &T 的引用, 和 &mut Wrapper<&mut T>自动取消对 &mut T 的引用.另外, Wrapper<T>如果 T 是可复制的是。

假设存在一个函数可以取 &Wrapper<&mut T>并将其强制为 &Wrapper<&T> :

fn downgrade_wrapper_ref<'a, 'b, T: ?Sized>(w: &'a Wrapper<&'b mut T>) -> &'a Wrapper<&'b T> {
unsafe {
// the internals of this function is not important
}
}

通过使用这个函数,可以同时获得对同一个值的可变和不可变引用:

fn main() {
let mut value: i32 = 0;

let mut x: Wrapper<&mut i32> = Wrapper(&mut value);

let x_ref: &Wrapper<&mut i32> = &x;
let y_ref: &Wrapper<&i32> = downgrade_wrapper_ref(x_ref);
let y: Wrapper<&i32> = *y_ref;

let a: &mut i32 = &mut *x;
let b: &i32 = &*y;

// these two lines will print the same addresses
// meaning the references point to the same value!
println!("a = {:p}", a as &mut i32); // "a = 0x7ffe56ca6ba4"
println!("b = {:p}", b as &i32); // "b = 0x7ffe56ca6ba4"
}

Full playground example

这在 Rust 中是不允许的,会导致未定义的行为并意味着函数 downgrade_wrapper_ref在这种情况下是不健全的。可能还有其他特定情况,作为程序员,您可以保证不会发生这种情况,但仍然需要您使用 unsafe 专门针对这些情况实现它。代码,以确保您负责做出这些保证。

关于rust - 为什么 Rust 不能在类型构造函数中将可变引用强制为不可变引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61173918/

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