Created
August 28, 2022 22:15
-
-
Save gftea/8df5d6cd96fdc6d06d4bc75f116cc00a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(unused)] | |
use std::rc::Rc; | |
use std::cell::RefCell; | |
#[derive(Debug, PartialEq)] | |
struct Node; | |
fn main() { | |
{ | |
// case 1, normal | |
let x = Rc::new(RefCell::new(Node)); | |
// `x.borrow()` is derived by compiler as below | |
// 1. Rc<RefCell<Node>> automatically dereferences to RefCell<Node> | |
// 2. then RefCell::borrow() is called | |
assert_eq!(*x.borrow(), Node); | |
} | |
{ | |
// case 2, trait pollution | |
// compiler cannot automatically dereferences due to ambiguity. | |
// because: `borrow` method can be from two traits implementations. | |
// - import `std::rc::Rc` add `impl<T> Borrow<T> for Rc<T>` | |
// - import `std::borrow::Borrow` add blanket implementation `impl<T> Borrow<T> for T` | |
use std::borrow::Borrow; | |
let x = Rc::new(RefCell::new(Node)); | |
{// error case | |
// assert_eq!(*x.borrow(), Node) // uncomment this line to see compiler error | |
} | |
{// solution 1 | |
use std::ops::Deref; // bring `Deref` to scope and use explicitly | |
assert_eq!(*x.deref().borrow(), Node); | |
} | |
{// solution 2 use full qualitfied type | |
// 1st borrow return RefCell<Node>, 2nd borrow return Ref<_,Node> | |
// <Rc<RefCell<Node>> as Borrow<RefCell<Node>>>::borrow(&x) is equivalent to x.deref() | |
// but x.deref() is much more concise. | |
assert_eq!(*<Rc<RefCell<Node>> as Borrow<RefCell<Node>>>::borrow(&x).borrow(), Node); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment