【发布时间】:2017-06-18 19:31:40
【问题描述】:
我真的不知道如何克服这一点。据我了解,words 被移动到闭包中(这对我来说很好,这是此后唯一要使用的地方)但根据typed_some 需要是 &mut 。错误暗示的想法听起来不错,只是那部分在库中,我不知道他们是否可以实现。on_edit documentation.
extern crate cursive;
extern crate rand;
use cursive::Cursive;
use cursive::views::{Dialog, TextView, EditView, LinearLayout};
use cursive::traits::Identifiable;
use rand::Rng;
fn main() {
// This really messes with stdout. Seems to disable it by default but when
// siv is running println prints in random places on the screen.
let mut siv = Cursive::new();
siv.add_global_callback('q', |s| s.quit());
let mut words = WordBar::new();
siv.add_layer(Dialog::around(LinearLayout::vertical()
.child(TextView::new(words.update_and_get_bar()).with_id("target_field"))
.child(EditView::new()
.on_edit(move |s, input, _| words.typed_some(s, input))
.with_id("input_field")))
.title("Keyurses")
.button("Quit", |s| s.quit()));
siv.run();
}
type WordList = Vec<&'static str>;
#[derive(Debug)]
struct WordBar {
words: WordList,
target_list: WordList,
}
impl WordBar {
fn new() -> Self {
WordBar {
words: include_str!("google-10000-english-usa.txt").lines().collect(),
target_list: vec!["foo"],
}
}
fn typed_some(&mut self, siv: &mut Cursive, input: &str) {
// See https://github.com/gyscos/Cursive/issues/102
// for discussion on this mess
let mut reset_input = false;
{
let target_word = siv.find_id::<TextView>("target_field").unwrap();
if target_word.get_content() == input {
target_word.set_content(self.update_and_get_bar());
reset_input = true;
}
}
if reset_input {
siv.find_id::<EditView>("input_field").unwrap().set_content("");
}
}
fn rand_word(&self) -> &'static str {
let mut rng = rand::thread_rng();
rng.choose(&self.words).unwrap()
}
fn update_and_get_bar(&mut self) -> String {
if self.target_list.len() > 0 {
self.target_list.pop();
}
while self.target_list.len() < 5 {
let new_word = self.rand_word();
self.target_list.push(new_word);
}
let mut bar_text: String = "".to_string();
for word in &self.target_list {
if bar_text == "" {
bar_text = word.to_string();
} else {
bar_text.push_str(" ");
bar_text.push_str(word);
}
}
bar_text
}
}
还有错误
error: cannot borrow captured outer variable in an `Fn` closure as mutable
--> src/main.rs:20:45
|
20 | .on_edit(move |s, input, _| words.typed_some(s, input))
| ^^^^^
|
help: consider changing this closure to take self by mutable reference
--> src/main.rs:20:26
|
20 | .on_edit(move |s, input, _| words.typed_some(s, input))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Repo link 如果你想克隆它,一切都会被推送。提交 633ed60 要具体。
【问题讨论】:
-
我认为您可能需要在闭包中将其作为
&mut借用,如下所示: .on_edit(move | s, input, _| { let words = &mut words; words.typed_some(s, input); }) 我无法测试它(在移动设备上)。 -
@WesleyWiser 谢谢,但我得到了同样的错误,只是稍微改写了bpaste.net/show/dde9cfc1c7fe
-
@WesleyWiser
EditView::on_edit需要带有Fn绑定的闭包,这意味着它不能改变其环境(除非通过像RefCell这样的逃生舱口,如我的回答所示)。跨度>