提问人:Christopher Miller 提问时间:2/7/2023 最后编辑:Christopher Miller 更新时间:2/8/2023 访问量:90
在 Rust 中,为什么可以将更高级别的引用分配给较低级别的引用,为什么不能反过来呢?
In Rust, why can higher-level references be assigned to lower-level references, and why not the other way around?
问:
Rust 允许将具有较高间接级别的引用分配给具有较低间接级别的引用。例如,编译器允许将 a 赋值给 :&&&&&&
&
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 &&&i32
expected &&i32, found integer
总的来说,我的主要问题是,当允许将较高的间接引用分配给较低的间接引用时,究竟为什么应该不允许将较低的间接性分配给较高的间接性引用?这两件事有什么不同,以至于它们的行为也一定不同?
答:
&&T
可以被强制执行,因为 deref 强制 (“ or to if implements ”) 和 impl Deref<Target = T> for &T
相反,因为不存在 .
通过重复应用可以被强制&T
&T
&mut T
&U
T
Deref<Target = U>
impl Deref<Target = &T> for T
&&&&&&T
&T
至于为什么一个是允许的,而另一个是不允许的,如果隐式引用在任何地方都允许,跟踪所有权会比现在更难,我们已经在方法接收器的自动引用方面遇到了这个问题。
let s = String::from("Hello");
my_fun(s);
如果不看一下我们是否允许自动引用的定义,就无法回答“是否被移动?”这个问题。s
my_fun
评论
i32
&i32
&&i32
&&&&&&i32
impl Deref<Target = &T> for T
评论