🧀 通过deref间接调用方法
昨天看 RefCell<T>
文档的时候,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#[derive(Debug)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let value = Rc::new(RefCell::new(5));
let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
*value.borrow_mut() += 10;
println!("a after = {:?}", a);
println!("b after = {:?}", b);
println!("c after = {:?}", c);
}
对于 *value.borrow_mut() += 10
的解释
After we’ve created the lists in a, b, and c, we want to add 10 to the value in value. We do this by calling borrow_mut on value, which uses the automatic dereferencing feature we discussed in Chapter 5 (see the section “Where’s the -> Operator?”) to dereference the Rc
to the inner RefCell value. The borrow_mut method returns a RefMut smart pointer, and we use the dereference operator on it and change the inner value.
这里让我不仅好奇,是不是这样的?
就是
1
x -- Deref --> y
类型x可以通过Deref得到类型y
假如 y 有一个方法 fn foo(&self)
那是不是 x可以直接调用这个foo,也就是 x.foo()
行得通?
结论是可以的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Tess{
val: String,
id: i32,
}
use std::ops::Deref;
impl Deref for Tess{
type Target = String;
fn deref(&self) -> &Self::Target{
&self.val
}
}
fn main(){
let a = Tess{val:"hello".to_string(),id:3};
println!("{}",*a);
println!("{}",a.len()); //直接调用String的方法len
}
/*
hello
5
*/
至于为什么,上面也提到了,主要涉及到两点,我认为
- when you call a method with object.something(), Rust automatically adds in &, &mut, or * so object matches the signature of the method
- Deref Coercion
因为1, a.len()
实际上是(&a).len()
因为2, &a
是&Tess
, 而fn len(&self)
这里其实是需要 &String
,然后通过 Deref Coercion 得到&String
,从而完成调用。
This post is licensed under CC BY 4.0 by the author.