Pointers “什么时候应该?”&&引用;在作业的双方都使用?
文档显示了一个示例,包括以下内容:Pointers “什么时候应该?”&&引用;在作业的双方都使用?,pointers,rust,dereference,borrow-checker,borrowing,Pointers,Rust,Dereference,Borrow Checker,Borrowing,文档显示了一个示例,包括以下内容: let pair = Arc::new((Mutex::new(false), Condvar::new())); // <snipped for brevity> let &(ref lock, ref cvar) = &*pair; 两个版本都编译;有语义上的区别吗?如果没有,是否有任何理由选择示例中出现的语法 一般来说,我仍在努力理解&*在Rust code中何时/何地应该出现。我的直觉是将这个字符组合视为不可操作,尽管我知
let pair = Arc::new((Mutex::new(false), Condvar::new()));
// <snipped for brevity>
let &(ref lock, ref cvar) = &*pair;
两个版本都编译;有语义上的区别吗?如果没有,是否有任何理由选择示例中出现的语法
一般来说,我仍在努力理解
&*
在Rust code中何时/何地应该出现。我的直觉是将这个字符组合视为不可操作,尽管我知道,因为Rust的Deref
语义,情况并非如此。在这种情况下使用&
并没有什么区别,因为LHS是一个。在我看来,这个例子不应该使用&
。但是,在其他情况下有一个重要区别:*
移动延迟值:
let p = *pair; // *Deref::deref(pair)
// pair cannot be used anymore because the deferred value was moved
let p = &*pair; // &*Deref::deref(pair)
// p: &(Mutex::new(false), Condvar::new())
// p and pair can be used
我仍在努力理解Rust代码中何时/何地应习惯性地出现&*
通常,当需要引用延迟值时,如在函数调用中,请使用&*
:
fn sum(a: &u32, b: &u32) -> u32 {
a + b
}
fn main() {
let x = Box::new(10);
// println!("{:?}", sum(&1, x)); // do not work x is Box<u32>
// println!("{:?}", sum(&1, *x)); // do not work *x is u32
println!("{:?}", sum(&1, &*x)); // ok &*x is &u32
}
fn和(a:&u32,b:&u32)->u32{
a+b
}
fn main(){
设x=Box::new(10);
//println!(“{:?}”,sum(&1,x));//不工作x为方框
//println!(“{:?}”,和(&1,*x));//不工作*x是u32
println!(“{:?}”,和(&1,&*x));//确定&*x是&u32
}
我的直觉是将这个字符组合视为不可操作,尽管我知道,由于Rust的Deref语义,情况并非如此
考虑到“
Deref
对于编写自定义指针类型很有用”,我喜欢将&*
读作“这个(智能)指针指向的值的引用”。这太棒了!你能为/*Deref::Deref(成对)
澄清一下为什么*
和Deref
都出现在你的解释中吗?难道不应该只有一个吗?编译器将*pair
转换为*Deref::Deref(pair)
,并将&*pair
转换为&*Deref::Deref(pair)
,考虑到Deref::Deref
返回&t
,然后*pair
生成t
,而&*pair
生成&t
,但是如果*pair
扩展到*Deref::Deref(pair)
,那么为什么不反过来扩展到*Deref::reference(*Deref::Deref(pair))
?也可以解释一下-这怎么不是递归的?我试图找到翻译是如何完成的官方描述,但没有成功。但是我假设每个*
都进行一次扩展,并且结果不会再次扩展。如果我找到一个官方的描述,我会更新答案。让我补充一下,我发现最有助于理解Deref行为背后的设计意图/思维。
fn sum(a: &u32, b: &u32) -> u32 {
a + b
}
fn main() {
let x = Box::new(10);
// println!("{:?}", sum(&1, x)); // do not work x is Box<u32>
// println!("{:?}", sum(&1, *x)); // do not work *x is u32
println!("{:?}", sum(&1, &*x)); // ok &*x is &u32
}