在Rust语言中, 一个方法的receiver默认并且总是正确的选择,即是:&self, &mut self , 偶尔也会用一下:self ; 同时Rust还允许如下形式的方法receiver: Box<Self>, Rc<Self>, Arc<Self> , 我在rust1.88.0 2024 edition stable 版本下做了代码实验, 以上形式Rust都支持,编译通过。
use std::{rc::Rc, sync::Arc};
struct At(u8);
impl At {
fn pb(self:Box<At>){
println!("Box: {}", self.0)
}
fn pr(self:Rc<At>){
println!("Rc: {}", self.0)
}
fn pa(self:Arc<At>){
println!("Arc: {}", self.0)
}
fn p(&self){
println!("raw:{}", self.0)
}
}
fn main() {
let p = At(100);
let pr = Rc::new(At(101));
let pb = Box::new(At(102));
let pa = Arc::new(At(103));
p.p();
pr.pr();
//pr.p(); //error: borrow of moved value.
pb.pb();
//pb.p(); //error: borrow of moved value.
pa.pa();
//pa.p(); //error: borrow of moved value.
}
Rust还有一个RFC #44874 , arbitrary_self_types feature, 大致意思是说:允许将一个自定义包裹类型作为方法的receiver, 在当前Rust版本,我仿照Box编写了一个简易版本的智能指针MyBox, 编译运行通过后, 我将MyBox<自定义类型>作为一个方法的receiver, 编译没通过,看来这个feature还没有stable, IDE的报错提示详细信息如下:
`MyBox<INT>` cannot be used as the type of `self`
without the `arbitrary_self_types` feature
see issue #44874
<https://github.com/rust-lang/rust/issues/44874> for more information
consider changing to `self`, `&self`, `&mut self`,
or a type implementing `Receiver`
such as `self: Box<Self>`, `self: Rc<Self>`,
or `self: Arc<Self>`rustc(Click for full compiler diagnostic)
mybox_as_receiver struct MyBox<T>(T)
权威资料说:作为方法的receiver : &self和&mut self 几乎总是正确的选择;即使遇到智能指针包裹形式的receiver,如: Box<Self>, Rc<Self>, Arc<Self>等, Rust也可以通过自动”解引用(Deref和DerefMut)” ,将其转化成&self或&mut self形式, 所以如无特别的理由和需求, 我们自己定义的方法的receiver采用原始直接形式传递即可,不必要采用包裹类型传递。下面是一个自定义类型作为方法receiver的实验:
//一个自定义类型作为方法的receiver.
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T>{
fn new(x:T)->MyBox<T>{
MyBox(x)
}
}
//还可以同时实现DerefMut trait来重载可变引用的*运算符。
//若是有需要清理的资源,还可以同时实现Drop trait.
impl<T> Deref for MyBox<T>{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
struct INT(u32);
impl INT{
fn add(self:MyBox<Self>, y:u32) -> u32{
(*self).0 +y
}
}
fn main() {
let x =5;
let y = MyBox::new(x);
assert_eq!(5, x);
assert_eq!(5,*y);
}
【编译报错】
> cargo build
Compiling mybox_as_receiver v0.1.0 (D:Workspace_Projs_Source_Code
ust_projsmybox_as_receiver)
error[E0658]: `MyBox<INT>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
--> srcmain.rs:25:17
|
25 | fn add(self:MyBox<Self>, y:u32) -> u32{
| ^^^^^^^^^^^
|
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
= help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
For more information about this error, try `rustc --explain E0658`.
error: could not compile `mybox_as_receiver` (bin "mybox_as_receiver") due to 1 previous error
我个人认为,上面6种方法receiver形式已经足够用了,没有必要将自定义包裹类型作为方法的receiver,Rust原有的智能指针类型已经足够了; 还不如自定义一个类型,然后为这个类型实现相应的方法呢!没有必要将receiver搞得太复杂!
最后再强调一下这6种可用形式: self, &self, &mut self, Box<Self>, Rc<Self>, Arc<Self>; 注意后3种receiver中的S是大写的呦!大写Self代表一个类型,小写self代表这个类型的一个实例或实例的引用。
注意:个人学习随笔,水平有限,若有谬误,望请海涵指正!

















暂无评论内容