Purpose: Break one mut short into two structures. If you use one structure with the host closure, then everything works well.

Lightweight code:

fn main() { let mut is_visible = true; let mut is_close = true; let mut function = |name:Option<&[u8]>, value:&[u8]| { if let Some(name) = name { match name { b"is_visible" => { is_visible = match value { b"ON" => true, b"OFF" => false, _=> false, }; }, _=>{}, } } }; Test::test_set_vars(&mut function); Test2::test_set_vars(&mut function); if is_visible { println!("VISIBLE OK"); } if is_close { println!("CLOSE OK"); } } pub struct Test { } impl Test { pub fn test_set_vars<F: FnMut(Option<&[u8]>, &[u8])>(mut function: F) { function(Some(b"is_close"), b"OFF"); function(Some(b"is_visible"), b"ON"); } } pub struct Test2 { } impl Test2 { pub fn test_set_vars<F: FnMut(Option<&[u8]>, &[u8])>(mut function: F) { function(Some(b"is_close"), b"ON"); function(Some(b"is_visible"), b"ON"); } } 

Running: https://play.rust-lang.org/?gist=f3d656088b19ee1b847db54036983584&version=stable

If you duplicate the closure, then everything goes well.

Code 2:

 fn main() { let mut is_visible = true; let mut is_close = true; Test::test_set_vars(|name:Option<&[u8]>, value:&[u8]| { if let Some(name) = name { match name { b"is_visible" => { is_visible = match value { b"ON" => true, b"OFF" => false, _=> false, }; }, _=>{}, } } }); Test2::test_set_vars(|name:Option<&[u8]>, value:&[u8]| { if let Some(name) = name { match name { b"is_visible" => { is_visible = match value { b"ON" => true, b"OFF" => false, _=> false, }; }, _=>{}, } } }); if is_visible { println!("VISIBLE OK"); } if is_close { println!("CLOSE OK"); } } pub struct Test { } impl Test { pub fn test_set_vars<F: FnMut(Option<&[u8]>, &[u8])>(mut function: F) { function(Some(b"is_close"), b"OFF"); function(Some(b"is_visible"), b"ON"); } } pub struct Test2 { } impl Test2 { pub fn test_set_vars<F: FnMut(Option<&[u8]>, &[u8])>(mut function: F) { function(Some(b"is_close"), b"ON"); function(Some(b"is_visible"), b"ON"); } } 

    1 answer 1

    The problem is not the transfer of the closure to two functions, but that the closure captures the mutable link to is_visible , which remains active until the end of the closure's life.

    You can limit the lifetime of the circuit by placing it in the block. Playground

    Or use non-lexical lifetimes from the night branch of the compiler: Playground

    • Seductively, it works. It does not always occur to limit the lifetime. - Denis Kotlyarov