2015-02-07 2 views
0

나는 옵션 Rc를, 그리고 RefCell을 사용하여 구조체의 연결 목록 정렬이 있습니다.합니까 RefCell :: 내용을 이동 빌려?

나는 그것을 위해 FMT : 디버그를 구현하고 싶습니다,하지만 사랑스러운 "빌린 컨텐츠 밖으로 이동할 수 없습니다"오류로 실행했다.

use std::fmt; 
use std::rc::{Rc, Weak}; 
use std::cell::RefCell; 

#[derive(Clone, Debug, Ord, Eq, PartialOrd, PartialEq)] 
struct NodeId {id: String} 

impl NodeId { 
    pub fn new(s: &str) -> NodeId { NodeId{id: s.to_string()}} 
} 

struct NodeInfo { 
    nodeid: NodeId, 
    prev: Option<Rc<RefCell<NodeInfo>>>, 
    next: Option<Rc<RefCell<NodeInfo>>>, 
} 

impl fmt::Debug for NodeInfo { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "NodeInfo({} {} {})", self.nodeid.id, 
     match self.prev { None => "none".to_string(), Some(ref n) => n.borrow().nodeid.id}, 
     match self.next { None => "none".to_string(), Some(ref n) => "some".to_string()}, 
     ) 
    } 
} 

fn main() {} 

이상적으로 디버그 출력은 .next 및 .previous 노드의 ID를 표시 할 수 있습니다. 그러나 Rust는 그들에게 접근을 허용하지 않습니다. 시도는 RefCell의 내용이 오류가 발생합니다) (.borrow,하지만 그 이유를 이해할 수 없다.

여기에 플레이 : http://is.gd/Sah7sT

답변

1

합니까 RefCell :: 차용을() 내용을 이동?

아니요. 빌리거나 전화를 걸면 꽤 손쉽게 처리됩니다.^_^

문제는 당신이 빌린 구조체 밖으로 id를 이동하려고하는 것입니다. 그것이 현재의 문자열을 떠나 clone을 사용하고, 아주 새로운 하나 반환, 대신

n.borrow().nodeid.id 

: StringCopy하지 않기 때문에 이것은 움직임이다

n.borrow().nodeid.id.clone() 
+0

감사 :

나는 반복을 피하기 위해 newtype은을 사용하도록 선택했습니다! 이 동작을 일으키는 Strings의 (비) 복사 가능성은 완전히 나를 피했습니다. –

3

가 확장하기 @ (절대적으로 정확) Shepmaster의 대답, 당신은 아이의 id를 작성하여,이 경우 문자열을 복사하는 것을 피할 수는 포맷터에 직접 노드.

impl fmt::Debug for NodeInfo { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "NodeInfo({} {:?} {:?})", self.nodeid.id, ChildNode(&self.prev), ChildNode(&self.next)) 
    } 
} 

struct ChildNode<'a>(&'a Option<Rc<RefCell<NodeInfo>>>); 

impl<'a> fmt::Debug for ChildNode<'a> { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     match *self.0 { 
      Some(ref n) => write!(f, "{}", n.borrow().nodeid.id), 
      None  => write!(f, "None"), 
     } 
    } 
} 
관련 문제