#![allow(dead_code)] fn main() { try_mutate_primitive_vars(); try_mutate_object_vars(); } fn try_mutate_primitive_vars() -> () { let mut n : i32 = 32; println!( "n before: {}", n ); triple_arg(n); println!( "n after: {}", n ); println!("calling triple_arg_by_ref…"); triple_arg_by_ref(&mut n); println!( "n after: {}", n ); println!( "We see we CAN modify a local var, if it's passed by reference!" ); println!( "" ); } fn triple_arg( mut k: i32 ) -> i32 { println!( " tripleArg: k={}", k ); k = 3*k; println!( " tripleArg: k={}", k ); return k; } fn triple_arg_by_ref( k: &mut i32 ) -> i32 { // If `k` is a &i32, then `*k` is an i32. // Treat it as if `*k` as your regular-int-variable, with `*` reminding you that // assigning to the var is visible by the person who called you. println!( " tripleArg: k={}", *k ); *k = 3*(*k); println!( " tripleArg: k={}", *k ); return *k; } #[derive (Debug)] struct Cat { name: String, is_happy: bool, claw_sharpness: f64, } fn try_mutate_object_vars() -> () { let mut meowser: Cat = Cat { name: "Ms Purrscratch".to_string(), is_happy: false, claw_sharpness: 0.8, }; println!("meowser holds {:?}", meowser ); println!("Uh-oh, eating the catnip plant:"); set_happiness(meowser, true); println!("meowser holds {:?}", meowser ); println!("Our local variable was not changed (normal pass-by-value)" ); println!("calling assign_to_arg…"); assign_to_arg(meowser); println!("meowser holds {:?}", meowser ); println!(""); println!("\nNow passing meowser by reference:"); println!("We can overwrite the contents of our local var, by passing a (mutable) ref:"); println!("calling overwrite_struct_by_ref…"); overwrite_struct_by_ref(&mut meowser); println!("meowser holds {:?}", meowser ); println!(""); println!("We can also modify individual fields; this still requires a mutable ref:"); set_happiness_by_ref(&mut meowser, true); println!("meowser holds {:?}", meowser ); println!("(It surprised the C programmer in me that when passing a struct by IMmutable ref,"); println!(" I still wasn't able to assign to its fields; that's a different concept,"); println!(" but rust's immutable-references encompass both (?)."); println!( "Other methods can change *fields* of my object.") } fn assign_to_arg( mut some_kat: Cat ) -> () { println!(" assignToArg: some_kat holds {:?}", some_kat); some_kat = Cat { name: "Kat".to_string(), is_happy: false, claw_sharpness: 0.4 }; println!(" assignToArg: some_kat holds {:?}", some_kat); } fn set_happiness( mut a_kat: Cat, new_high_on_catnip : bool) -> () { println!(" set_happiness: a_kat holds {:?}", a_kat); a_kat.is_happy = new_high_on_catnip; println!(" set_happiness: a_kat holds {:?}", a_kat); } fn set_happiness_by_ref( a_kat: &mut Cat, new_happiness : bool) -> () { println!(" set_happiness_by_ref: a_kat holds {:?}", *a_kat); (*a_kat).is_happy = new_happiness; println!(" set_happiness_by_ref: a_kat holds {:?}", *a_kat); } fn overwrite_struct_by_ref( a_kat: &mut Cat) -> () { println!(" overwrite_struct_by_ref: a_kat holds {:?}", *a_kat); *a_kat = Cat {name: "tigger".to_string(), is_happy: false, claw_sharpness: 0.25}; println!(" overwrite_struct_by_ref: a_kat holds {:?}", *a_kat); }