| Add closures and unsafe; base16ct's lower.rs and upper.rs go through 0a375d8 nandithebull 12h ago | 1 | // `unsafe` is a permission marker, not a semantic change: it does not alter |
| 2 | // what the enclosed operations mean, so the block is transparent and each |
| 3 | // operation inside still goes through the ordinary lowering. |
| 4 | // |
| 5 | // Nim's closures capture by reference, as Rust's non-`move` closures do. |
| 6 | |
| 7 | fn apply(f: impl Fn(i32) -> i32, x: i32) -> i32 { |
| 8 | f(x) |
| 9 | } |
| 10 | |
| 11 | fn twice(x: i32) -> i32 { |
| 12 | x * 2 |
| 13 | } |
| 14 | |
| 15 | fn halve(n: i32) -> Result<i32, i32> { |
| 16 | if n % 2 == 0 { Ok(n / 2) } else { Err(n) } |
| 17 | } |
| 18 | |
| 19 | fn as_str(b: &[u8]) -> &str { |
| 20 | unsafe { core::str::from_utf8_unchecked(b) } |
| 21 | } |
| 22 | |
| 23 | fn main() { |
| 24 | let add_one = |x: i32| x + 1; |
| 25 | println!("{}", apply(add_one, 10)); |
| 26 | println!("{}", apply(twice, 10)); |
| 27 | println!("{}", apply(|x: i32| x * x, 7)); |
| 28 | |
| 29 | // A closure capturing an enclosing binding, by reference. |
| 30 | let base: i32 = 100; |
| 31 | let shift = |x: i32| x + base; |
| 32 | println!("{}", apply(shift, 5)); |
| 33 | |
| 34 | // `.map` over a Result: the closure's parameter type comes from the |
| 35 | // receiver, and the error branch is carried through untouched. |
| 36 | println!("{:?}", halve(8).map(|v| v * 10)); |
| 37 | println!("{:?}", halve(7).map(|v| v * 10)); |
| 38 | |
| 39 | // `&str` is a view of someone else's bytes, not a copy. |
| 40 | let bytes: Vec<u8> = vec![104, 105]; |
| 41 | println!("{} {}", as_str(&bytes), as_str(&bytes).len()); |
| 42 | |
| 43 | let n: i32 = unsafe { twice(21) }; |
| 44 | println!("{}", n); |
| 45 | } |