1
Expat XML 구문 분석기 용 Rust 래퍼를 구현하려고합니다. 나는 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()는 변경 가능한 고유 포인터를 절대적으로 요구합니다. 관리 포인터로 작동하는 내 자신의 벡터를 구현해야합니까? –
특정 문제를 해결하기 위해 예제를 업데이트했습니다. –
와우, 너무 간단 : 관리 상자 안에있는 고유 한 상자가 작동합니다. 도와 주셔서 감사합니다! –