// `unsafe` is a permission marker, not a semantic change: it does not alter // what the enclosed operations mean, so the block is transparent and each // operation inside still goes through the ordinary lowering. // // Nim's closures capture by reference, as Rust's non-`move` closures do. fn apply(f: impl Fn(i32) -> i32, x: i32) -> i32 { f(x) } fn twice(x: i32) -> i32 { x * 2 } fn halve(n: i32) -> Result { if n % 2 == 0 { Ok(n / 2) } else { Err(n) } } fn as_str(b: &[u8]) -> &str { unsafe { core::str::from_utf8_unchecked(b) } } fn main() { let add_one = |x: i32| x + 1; println!("{}", apply(add_one, 10)); println!("{}", apply(twice, 10)); println!("{}", apply(|x: i32| x * x, 7)); // A closure capturing an enclosing binding, by reference. let base: i32 = 100; let shift = |x: i32| x + base; println!("{}", apply(shift, 5)); // `.map` over a Result: the closure's parameter type comes from the // receiver, and the error branch is carried through untouched. println!("{:?}", halve(8).map(|v| v * 10)); println!("{:?}", halve(7).map(|v| v * 10)); // `&str` is a view of someone else's bytes, not a copy. let bytes: Vec = vec![104, 105]; println!("{} {}", as_str(&bytes), as_str(&bytes).len()); let n: i32 = unsafe { twice(21) }; println!("{}", n); }