2

次のコードを検討してください。

use std::collections::HashMap;
type KeyCode = char;
type CmdType = Fn(&mut E);

struct E {
    key_map: HashMap<KeyCode, Box<CmdType>>,
}

impl E {
    fn map_key(&mut self, key: KeyCode, function: Box<CmdType>) {
        self.key_map.insert(key, function);
    }
    fn quit(&mut self) { println!("quitting"); /* ... */ }
}

fn main() {
    let mut e = E { key_map: HashMap::new() };
    e.map_key('q', Box::new(|e: &mut E| e.quit()));

    match e.key_map.get(&'q') {
        Some(f) => f(&mut e),
        None => {}
    }
}

に渡そうとしているため、コンパイルされません:ef

も不変として借りられるeため、可変として借りることはできませんe.key_map

しかし、 の借用がe.key_map終了すると、 にアクセスできなくなりますf。では、マップ内にあるクロージャーを正確に呼び出すにはどうすればよいでしょうか?

4

2 に答える 2

1

では、マップ内にあるクロージャーを正確に呼び出すにはどうすればよいでしょうか?

これは、適切な動作によって異なります。

が から借用されている場合、呼び出しf(&mut e)は不可能です。解決策はfe

  • 関数に渡さないでください&mut eEあなたの管理下にない場合、これは実用的ではありません。

  • fからの借り入れはやめましょうe。できないので、単純にコピーすることはできませCmdTypeん。ただし、マップからClone一時的に削除できるはずです。f

    let removed = e.key_map.remove(&'q');
    if let Some(f) = removed {
        f(&mut e);
        e.key_map.insert('q', f);
    }
    
于 2015-08-20T02:35:43.347 に答える