|
67 | 67 | //! mutability:
|
68 | 68 | //!
|
69 | 69 | //! ```
|
| 70 | +//! use std::cell::{RefCell, RefMut}; |
70 | 71 | //! use std::collections::HashMap;
|
71 |
| -//! use std::cell::RefCell; |
72 | 72 | //! use std::rc::Rc;
|
73 | 73 | //!
|
74 | 74 | //! fn main() {
|
75 | 75 | //! let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
|
76 |
| -//! shared_map.borrow_mut().insert("africa", 92388); |
77 |
| -//! shared_map.borrow_mut().insert("kyoto", 11837); |
78 |
| -//! shared_map.borrow_mut().insert("piccadilly", 11826); |
79 |
| -//! shared_map.borrow_mut().insert("marbles", 38); |
| 76 | +//! // Create a new block to limit the scope of the dynamic borrow |
| 77 | +//! { |
| 78 | +//! let mut map: RefMut<_> = shared_map.borrow_mut(); |
| 79 | +//! map.insert("africa", 92388); |
| 80 | +//! map.insert("kyoto", 11837); |
| 81 | +//! map.insert("piccadilly", 11826); |
| 82 | +//! map.insert("marbles", 38); |
| 83 | +//! } |
| 84 | +//! |
| 85 | +//! // Note that if we had not let the previous borrow of the cache fall out |
| 86 | +//! // of scope then the subsequent borrow would cause a dynamic thread panic. |
| 87 | +//! // This is the major hazard of using `RefCell`. |
| 88 | +//! let total: i32 = shared_map.borrow().values().sum(); |
| 89 | +//! println!("{}", total); |
80 | 90 | //! }
|
81 | 91 | //! ```
|
82 | 92 | //!
|
|
102 | 112 | //!
|
103 | 113 | //! impl Graph {
|
104 | 114 | //! fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> {
|
105 |
| -//! // Create a new scope to contain the lifetime of the |
106 |
| -//! // dynamic borrow |
107 |
| -//! { |
108 |
| -//! // Take a reference to the inside of cache cell |
109 |
| -//! let mut cache = self.span_tree_cache.borrow_mut(); |
110 |
| -//! if cache.is_some() { |
111 |
| -//! return cache.as_ref().unwrap().clone(); |
112 |
| -//! } |
113 |
| -//! |
114 |
| -//! let span_tree = self.calc_span_tree(); |
115 |
| -//! *cache = Some(span_tree); |
116 |
| -//! } |
| 115 | +//! self.span_tree_cache.borrow_mut() |
| 116 | +//! .get_or_insert_with(|| self.calc_span_tree()) |
| 117 | +//! .clone() |
| 118 | +//! } |
117 | 119 | //!
|
118 |
| -//! // Recursive call to return the just-cached value. |
119 |
| -//! // Note that if we had not let the previous borrow |
120 |
| -//! // of the cache fall out of scope then the subsequent |
121 |
| -//! // recursive borrow would cause a dynamic thread panic. |
122 |
| -//! // This is the major hazard of using `RefCell`. |
123 |
| -//! self.minimum_spanning_tree() |
| 120 | +//! fn calc_span_tree(&self) -> Vec<(i32, i32)> { |
| 121 | +//! // Expensive computation goes here |
| 122 | +//! vec![] |
124 | 123 | //! }
|
125 |
| -//! # fn calc_span_tree(&self) -> Vec<(i32, i32)> { vec![] } |
126 | 124 | //! }
|
127 | 125 | //! ```
|
128 | 126 | //!
|
|
0 commit comments