Мне нужно инициализировать элемент (fn init(&mut self) -> Option<&Error>
) и использовать его, если ошибок нет.матч + 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
}
}
Fair. Необходимо использовать 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 loan conundrum] (http://stackoverflow.com/questions/30243606/if-let-borrow-conundrum) – malbarbo
@malbarbo Я не думаю, что это точно так же, как тот. Это связано с возвратом ссылки с помощью метода '& mut self'. Это приводит к тому, что изменчивый долг сохраняется. [example] (https://play.rust-lang.org/?gist=5a6c22cd3d19b5b5eb9f3a759ecb84aa) – Shepmaster