在Rust中,为什么高级引用可以分配给低级引用,为什么不能反过来?

yftpprvb  于 2023-02-08  发布在  其他
关注(0)|答案(1)|浏览(134)

Rust允许将具有较高间接级别的引用赋给具有较低间接级别的引用。例如,编译器允许将&&&&&&赋给&

fn main() {
    let mut some_number = 5;

    // assign an &&&&&&i32 to an &i32, which works.
    let reference : &i32 = &&&&&&some_number;
}

这也适用于函数参数:

fn main() {
    let num = 5;

    // ref1 is an &&i32
    let ref1 = &#
    
    // Pass an &&i32 to a function parameter, which itself is an &i32 (works)
    func(ref1);
}

fn func(test: &i32) {
    println!("^^^^ This works!");
}

我了解到这是因为自动解引用,它允许Rust编译器根据需要解引用一个类型以匹配其他类型(如果我在这方面有错误,请纠正我)。
然而,Rust似乎不允许将较低的间接引用分配给较高的间接引用:

fn main() {
    let num = 5;
    
    // Try assigning an &i32 to an &&i32 (error)
    let ref1 : &&i32 = #
}

这会导致expected &i32, found integer编译器错误。我们在使用函数参数测试时也会遇到类似的编译器错误:

fn main() {
    let num = 5;
    
    // ref1 is an &&&i32
    let ref1 = &&#
    
    // Try passing an &&&i32 to a function parameter of type &&&&&i32 (error)
    func(ref1);
}

fn func(test: &&&&&i32) {
    println!("^^^^^^^^ This does not work!")
}

在这里,我们也得到了一个mismatched types错误,但我很好奇的是,编译器的输出并不完全是我们所期望的。编译器错误是expected &&i32, found integer。似乎编译器取消引用了两个引用,直到其中一个不再是引用-为什么它取消引用了两个引用?我以为它只解引用传递给函数的内容。
总的来说,我的主要问题是为什么在允许将较高间接引用分配给较低间接引用时,却不允许将较低间接引用分配给较高间接引用?这两件事有什么不同,以至于它们的行为也必须不同?

kgsdhlau

kgsdhlau1#

&&T可以强制为&T,因为deref强制(“如果T实现Deref<Target = U>,则&T&mut T强制为&U“),而impl Deref<Target = T> for &T不可能以其他方式强制,因为不存在impl Deref<Target = &T> for T。通过重复应用,&&&&&&T可以强制为&T
至于为什么一个是允许的,而另一个是不好的,如果隐式引用是允许的,跟踪所有权将比目前更难,我们已经有这个问题与方法接收者的自动引用。

let s = String::from("Hello");
my_fun(s);

如果我们允许自动引用,那么如果不查看my_fun的定义,就无法回答“s是否被移动了?”

相关问题