我需要初始化一個項目(fn init(&mut self) -> Option<&Error>
),並在沒有錯誤的情況下使用它。match + RefCell = X活不夠長
pub fn add(&mut self, mut m: Box<Item>) {
if let None = m.init() {
self.items.push(m);
}
}
這工作,除非我需要檢查錯誤,如果有任何:
pub fn add(&mut self, mut m: Box<Item>) {
if let Some(e) = m.init() {
//process error
} else {
self.items.push(m); //won't compile, m is borrowed
}
}
博覽會。需要使用RefCell
。然而,這
pub fn add(&mut self, mut m: Box<Item>) {
let rc = RefCell::new(m);
if let Some(e) = rc.borrow_mut().init() {
//process error
} else {
self.items.push(rc.borrow_mut())
}
}
怪異
error: `rc` does not live long enough
if let Some(e) = rc.borrow_mut().init() {
^~
note: reference must be valid for the destruction scope surrounding block at 75:60...
pub fn add_module(&mut self, mut m: Box<RuntimeModule>) {
^
note: ...but borrowed value is only valid for the block suffix following statement 0 at 76:30
let rc = RefCell::new(m);
結束我試過幾乎所有:普通的盒子,Rc
'編輯框,RefCell
' 編輯框,Rc
「編RefCell
。試圖去適應this answer我的情況。沒用。
完整的示例:
use std::cell::RefCell;
use std::error::Error;
trait Item {
fn init(&mut self) -> Option<&Error>;
}
struct ItemImpl {}
impl Item for ItemImpl {
fn init(&mut self) -> Option<&Error> {
None
}
}
//===========================================
struct Storage {
items: Vec<Box<Item>>,
}
impl Storage {
fn new() -> Storage {
Storage{
items: Vec::new(),
}
}
fn add(&mut self, mut m: Box<Item>) {
let rc = RefCell::new(m);
if let Some(e) = rc.borrow_mut().init() {
//process error
} else {
self.items.push(*rc.borrow_mut())
}
}
}
fn main() {
let mut s = Storage::new();
let mut i = Box::new(ItemImpl{});
s.add(i);
}
UPD:作爲建議,這是像我做了一個 「家庭」 的錯誤,這是很好的解釋here。但是我的情況有更簡單的解
的'RefCell'不會解決這個問題。這是借用檢查器的知識侷限性,並且有關於此的一些問題/答案。我指出了一個可能的重複,但我認爲我們應該找到一個明確的答案(如果可能的話)。 @Shepmaster你知道更好的重複嗎? – malbarbo
[If let borrow conundrum]可能的重複(http://stackoverflow.com/questions/30243606/if-let-borrow-conundrum) – malbarbo
@malbarbo我不認爲它和那個完全一樣。它與從'&mut self'方法返回引用有關。這會導致可變借款持續下去。 [示例](https://play.rust-lang.org/?gist=5a6c22cd3d19b5b5eb9f3a759ecb84aa) – Shepmaster