Я пытаюсь реализовать оболочку Rust для парсера Expat XML. Я завернул start_element, END_ELEMENT обратных вызовов, и они прекрасно работают в простых случаях (например, просто подсчет XML элементов) следующим образом:Несколько управляемых закрытий с общим состоянием?
struct Expat {
parser: expat::XML_Parser
}
type StartHandler = @fn(tag: &str, attrs: &[~str]);
type EndHandler = @fn(tag: &str);
type TextHandler = @fn(text: &str);
struct Handlers {
start_handler: StartHandler,
end_handler: EndHandler,
text_handler: TextHandler
}
impl Expat {
pub fn handlers(&self, start_handler: StartHandler, end_handler: EndHandler, text_handler: TextHandler) {
let handlers = @Handlers {
start_handler: start_handler,
end_handler: end_handler,
text_handler: text_handler
};
// How to do this properly?
unsafe { cast::bump_box_refcount(handlers) };
expat::XML_SetUserData(self.parser, unsafe { cast::transmute(&*handlers) });
}
я могу передать простые управляемые затворов для обработчиков() и иметь их обновлять @mut UINT значения.
Теперь я хочу, чтобы сохранить текущий XPath через обратные вызовы и возникают проблемы:
let mut xpath: ~[~str] = ~[];
let xpath_start_handler: @fn(&str, &[~str]) = |tag: &str, _attrs: &[~str]| {
vec::push(&xpath, tag.to_owned());
println(fmt!(" start: %?", xpath));
};
let xpath_end_handler: @fn(&str) = |tag: &str| {
println(fmt!(" end: %?", xpath));
let top = vec::pop(&xpath);
if top != tag.to_owned() {
fail!(fmt!("expected end tag: %s, received end tag: %s", top, tag));
}
};
let xpath_text_handler: @fn(&str) = |_text: &str| {
};
expat.handlers(xpath_start_handler, xpath_end_handler, xpath_text_handler);
Компилятор говорит, что единственный вектор XPath был перемещен в крышку xpath_start_handler и не могут быть доступны в xpath_end_closure.
Итак, мой вопрос - это лучший способ поддерживать изменяемое состояние во многих управляемых замыканиях?
Я сделал коробки для подсчета элементов XML, и это сработало нормально. Однако в этом случае vec :: push() абсолютно настаивает на изменяемом уникальном указателе. Нужно ли реализовать собственный вектор, который работает с управляемыми указателями? –
Обновленный пример, чтобы решить вашу конкретную проблему. –
Ничего себе, так просто: уникальная коробка внутри управляемой коробки, и она работает. Спасибо за помощь! –