Tôi có một vấn đề với các checker mượn khi sử dụng những đặc điểm như tham số kiểu trong một cấu trúc:kiểm tra Mượn thất bại khi sử dụng những đặc điểm như tham số kiểu
trait Trait {}
struct FooBar;
impl Trait for FooBar{}
struct Observer<Arg> {
action: Box<Fn(Arg) + Send>,
// Other fields
}
impl <Arg> Observer<Arg> {
fn new(action: Box<Fn(Arg) + Send>) -> Observer<Arg> {
Observer{action: action}
}
fn execute(&self, arg: Arg) {
(*self.action)(arg);
}
}
fn test() {
let mut foobar = FooBar;
{
let mut observer = Observer::new(Box::new(|&: param: &mut Trait| {
// do something with param here
}));
observer.execute(&mut foobar); // First borrow passes ...
observer.execute(&mut foobar); // This fails as "foobar" is already borrowed
} // The previous borrow ends here (lifetime of "observer")
}
Đầu ra là:
error: cannot borrow `foobar` as mutable more than once at a time
observer.execute(&mut foobar); // This fails as "foobar" is already borrowed
^~~~~~
note: previous borrow of `foobar` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `foobar` until the borrow ends
observer.execute(&mut foobar); // First borrow passes ...
^~~~~~
note: previous borrow ends here
{
...
} // The previous borrow ends here (lifetime of "observer")
^
Tuy nhiên, ví dụ sau hoạt động:
trait Trait {}
struct FooBar;
impl Trait for FooBar{}
struct Observer {
action: Box<Fn(&mut Trait) + Send>,
// Other fields
}
impl Observer {
fn new(action: Box<Fn(&mut Trait) + Send>) -> Observer {
Observer{action: action}
}
fn execute(&self, arg: &mut Trait) {
(*self.action)(arg);
}
}
fn test() {
let mut foobar = FooBar;
{
let mut observer = Observer::new(Box::new(|&: param: &mut Trait| {
// do something with param here
}));
observer.execute(&mut foobar);
observer.execute(&mut foobar);
}
}
Điều này có vẻ thực sự lạ đối với tôi, ví dụ thứ hai chỉ là một instanti ation của ví dụ đầu tiên, và tôi có thể (đau đớn) thực hiện điều tương tự với các macro.
Tôi đoán đây là khá phức tạp, như tôi cần phải biết kiểu của tham số thực hiện bởi việc đóng cửa, nhưng tôi không cần phải lưu trữ tài liệu tham khảo này ...
Đây có phải là một lỗi trong vay người kiểm tra? Hay tôi đang làm gì sai?
rustc 1.0.0-nightly (44a287e6e 2015-01-08 17:03:40 -0800)
EDIT 1: precised các trường hợp sử dụng
EDIT 2: Như đã giải thích trong câu trả lời dưới đây, vấn đề là các checker mượn buộc cuộc đời của Observer<&mut Type>
để được giống như các &mut Type
, vì vậy trong thực tế vấn đề không liên quan đến thực tế là chúng ta sử dụng một đặc điểm như một tham số kiểu (nó giống như một cấu trúc thực tế).
Vì vậy, trong trường hợp của tôi, tôi có thể có một cách giải quyết bằng cách định nghĩa Observer<Arg>
như thế này:
struct Observer<Arg> {
action: Box<Fn(&mut Arg) + Send>,
}
nên tham số kiểu Arg bản thân không phải là một tài liệu tham khảo, nhưng điều này làm cho đoạn code dưới generic. Bất kỳ ai có một giải pháp tốt hơn?