[英]use an object inside a closure which is passed to a method of that object
i have a struct Screen with its implementation我有一个结构屏幕及其实现
pub struct Screen {
stdin: Stdin,
// types are irrelevant
stdout: MouseStdout,
}
impl Screen {
// ...
pub fn handle_keys_loop<F: FnMut(&Event) -> ()>(
&self,
mut handler: F,
) {
let stdin = stdin();
for e in stdin.events() {
let e = e.unwrap();
match e {
Event::Key(Key::Ctrl('c')) => break,
_ => {
handler(&e);
},
}
}
}
}
and usage (which is wrong and know it)和用法(这是错误的并且知道)
let mut screen = Screen::new();
screen.init_screen();
screen.handle_keys_loop(|event| {
match event {
Event::Key(Key::Char('a')) => {
screen.println("hello there",15, 1, true);
},
_ => {}
}
});
screen.end_screen();
the error is错误是
error[E0502]: cannot borrow `screen` as mutable because it is also borrowed as immutable
--> src/bin/terminal.rs:74:29
|
74 | screen.handle_keys_loop(|event| {
| - ---------------- ^^^^^^^ mutable borrow occurs here
| | |
| _____| immutable borrow later used by call
| |
75 | | match event {
76 | | Event::Key(Key::Char('a')) => {
77 | | println!("{} {} {} {}", "do something with a", 15, 1, true);
78 | | // tried to borrow as mutable
79 | | screen.println("hello there",15, 1, true);
| | ------ second borrow occurs due to use of `screen` in closure
... |
82 | | }
83 | | });
| |______- immutable borrow occurs here
and if i make self
mut inside handle_keys_loop
to get rid of cannot borrow
screen as mutable because it is also borrowed as immutable
如果我在
handle_keys_loop
中进行self
mut 以摆脱cannot borrow
borrow screen as mutable because it is also borrowed as immutable
pub fn handle_keys_loop<F: FnMut(&Event) -> ()>(
+ &mut self,
- &self
....
i get this error我收到这个错误
error[E0499]: cannot borrow `screen` as mutable more than once at a time
--> src/bin/terminal.rs:74:29
|
74 | screen.handle_keys_loop(|event| {
| - ---------------- ^^^^^^^ second mutable borrow occurs here
| | |
| _____| first borrow later used by call
| |
75 | | match event {
76 | | Event::Key(Key::Char('a')) => {
77 | | screen.println("hello there",15, 1, true);
| | ------ second borrow occurs due to use of `screen` in closure
... |
80 | | }
81 | | });
| |______- first mutable borrow occurs here
what im trying to do: use the method handle_keys_loop
of screen
and pass screen
inside the closure, which is passed to handle_keys_loop
.我想做什么:使用
screen
的方法handle_keys_loop
并在闭包内传递screen
,它被传递给handle_keys_loop
。 basically, to use screen
inside of screen
.基本上,在
screen
内部使用screen
。
how do i achieve that?我该如何实现?
some people told me to use RefCell
, but that didnt work out very well, i got BorrowError.有些人告诉我使用
RefCell
,但效果不是很好,我得到了 BorrowError。
i will use any workaround to just use screen inside the closure which is passed to screen's method.我将使用任何解决方法来仅在传递给屏幕方法的闭包内使用屏幕。
thanks in advance.提前致谢。
One pattern I use to handle such a situation is to pass self: &mut Self
back into the closure from handle
and use that inside the closure.我用来处理这种情况的一种模式是将
self: &mut Self
从handle
传递回闭包,并在闭包内使用它。 A simplified version of your code:您的代码的简化版本:
struct Screen {}
struct Event {}
impl Screen {
fn handle<F: FnMut(&mut Screen, Event)>(&mut self, mut handler: F) {
handler(self, Event {})
}
fn print(&mut self) {}
}
fn main() {
let mut screen = Screen {};
screen.handle(|screen, _event| screen.print());
screen.handle(|screen, _event| screen.print());
}
You can't do what you're trying to do because it violates Rust's rule that you can't mutate a value while something else has access to it.你不能做你想做的事,因为它违反了 Rust 的规则,即当其他东西可以访问它时你不能改变一个值。
However, your handle_keys_loop
method doesn't even use self
which means the &self
parameter is redundant.但是,您的
handle_keys_loop
方法甚至不使用self
这意味着&self
参数是多余的。 There's no reason to give a function an argument it's not going to use (except when implementing a trait that requires it).没有理由给 function 一个它不会使用的参数(除非在实现需要它的特征时)。
Just remove the argument:只需删除参数:
pub fn handle_keys_loop<F: FnMut(&Event) -> ()>(
mut handler: F,
) {
And call it as Screen::handle_keys_loop(|event| {... })
.并将其称为
Screen::handle_keys_loop(|event| {... })
。
Alternatively, make it a free function, external to Screen
entirely, since it doesn't depend on Screen
in any way.或者,将其设为完全在
Screen
外部的免费 function,因为它不以任何方式依赖于Screen
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.