Skip to content

Commit a080be9

Browse files
committed
add own!() macro
1 parent 18d22e1 commit a080be9

File tree

1 file changed

+63
-6
lines changed

1 file changed

+63
-6
lines changed

src/lib.rs

+63-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,64 @@
1-
#[cfg(test)]
2-
mod tests {
3-
#[test]
4-
fn it_works() {
5-
assert_eq!(2 + 2, 4);
6-
}
1+
// -------------------------------------
2+
// ----------- CUSTOM MACROS -----------
3+
4+
#[macro_export]
5+
/// Use to take mutable ownership of _specific_ variables within a closure.
6+
///
7+
/// Closures try to be "smart" about how much scope they capture. If you don't mutate a variable
8+
/// they take `&var`, if you do mutate they take `&mut var`. However, if you require ownership you use
9+
/// `move`, i.e. `move || {... do stuff with var...}`... _right_?
10+
///
11+
/// The problem with `move` is that it moves _every_ variable that is referenced. If you only need
12+
/// to move _one_ variable it can be a pain. Interestingly, you can tell the compiler to only move
13+
/// _specific_ variables like so:
14+
///
15+
/// ```no_compile
16+
/// let x = x;
17+
/// let y = y;
18+
/// // ... etc
19+
/// ```
20+
///
21+
/// But this is quite silly and not obvious to someone who doesn't know about it. Instead, use the
22+
/// `own!` macro and your code will be self documenting.
23+
///
24+
/// > Note: this macro always does `let mut x = x` to mimick its primary usecase of closures
25+
/// > (which infer mutability automatically). If you require non-mutable ownership use `let x = x`
26+
/// > directly.
27+
///
28+
/// # Examples
29+
/// ```
30+
/// #[macro_use] extern crate std_prelude;
31+
///
32+
/// # fn main() {
33+
/// let y = vec![1, 2, 3];
34+
/// let mut x = vec![1, 2, 3];
35+
/// let z = vec![10];
36+
///
37+
/// // create scope in which we mutate `x`
38+
/// {
39+
/// let closure = || {
40+
/// own!(y, z);
41+
/// x.push(4); // mutate reference to x
42+
/// z.push(10);
43+
///
44+
/// println!("&x: {:?}", &x);
45+
/// println!("moved y: {:?}", y);
46+
/// println!("moved z: {:?}", z);
47+
/// };
48+
///
49+
/// closure();
50+
/// }
51+
///
52+
/// println!("&x after: {:?}", x); // We can still print x!
53+
/// // println!("y after: {:?}", y); // ERROR: use of moved value
54+
/// // println!("z after: {:?}", z); // ERROR: use of moved value
55+
/// # }
56+
/// ```
57+
macro_rules! own {
58+
( $( $x:ident ),* ) => {
59+
#[allow(unused_mut)]
60+
$(
61+
let mut $x = $x;
62+
)*
63+
};
764
}

0 commit comments

Comments
 (0)