Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 获取对Rc后面的对象的引用_Rust - Fatal编程技术网

Rust 获取对Rc后面的对象的引用

Rust 获取对Rc后面的对象的引用,rust,Rust,我试图实现简单的DOM结构,但却被锈迹(或非锈迹)内存模型弄糊涂了 下面是一个简单的例子: struct NodeData { text: String, } struct Node(Rc<RefCell<NodeData>>); impl Node { fn new() -> Node { Node(Rc::new(RefCell::new(NodeData { text: String::new()

我试图实现简单的DOM结构,但却被锈迹(或非锈迹)内存模型弄糊涂了

下面是一个简单的例子:

struct NodeData {
    text: String,
}

struct Node(Rc<RefCell<NodeData>>);

impl Node {
    fn new() -> Node {
        Node(Rc::new(RefCell::new(NodeData {
            text: String::new()
        })))
    }

    fn set_text(&self, text: String) {
        self.0.borrow_mut().text = text;
    }

    // it works, but has unneeded, expensive clone
    // pub fn text(&self) -> String {
    //     self.0.borrow().text.clone()
    // }

    pub fn text(&self) -> &String {
        // ???
    }
}

fn main() {
    let node = Node::new();
    node.set_text("text".to_string());
    if node.text() == "text" {
        println!("equal");
    }
}
struct NodeData{
文本:字符串,
}
结构节点(Rc);
impl节点{
fn new()->节点{
节点(Rc::new(RefCell::new)(NodeData{
text:String::new()
})))
}
fn set_text(&self,text:String){
self.0.borrow_mut().text=text;
}
//它可以工作,但有不必要的昂贵克隆
//发布fn文本(&self)->字符串{
//self.0.borrow().text.clone()
// }
发布fn文本(&self)->字符串(&S){
// ???
}
}
fn main(){
让node=node::new();
node.set_text(“text.to_string());
如果node.text()=“文本”{
println!(“相等”);
}
}
我不明白如何获取文本字段的引用,不是它的副本

我只看到两种选择:

  • 使用
    RcString(Rc)
    代替原始
    String
    。但它会产生大量样板代码和一些开销
  • 这样的实现方法是\u text\u equal(&self,text:&String)
    。但是很难看
  • 还有一种可能性,就是我做了一些完全错误的事情。

    解释 这里的问题是,您正在
    RefCell
    中管理某些内容(
    NodeData
    )。为了使
    RefCell
    工作,它不能无限制地给出引用。相反,获取对内部数据的引用的唯一方法是使用范围保护。从:

    问题是只要
    Ref
    对象处于活动状态,
    Ref单元格的内部值就被认为是不可变的借用。在本例中,
    text
    是一个
    Ref
    对象,因此借用了内部值。在
    set_text
    中,您尝试可变地借用内部值


    当然,您也可以自己实现一些实用功能,正如您已经说过的(2)

    老实说,我想说你应该重新考虑你的设计。是否真的需要
    RefCell
    ?通常情况并非如此。通常,
    RefCells
    仅用于私有隐藏变量,从不向用户公开。上述问题是不这样做的原因之一

    当然,这个答案不是很令人满意,但我认为没有更好的解决办法

    附加提示
    • &String
      引用并不比
      &str
      引用更强大。因此通常只使用
      &str
      。这同样适用于
      &Vec
      (很少使用)和
      &T]
      。请注意,这仅对不可变引用有效--
      &mut String
      &mut str
      强大得多

    感谢您的详细解释,但据我所知,我应该返回
    Ref
    ,而不是
    Ref
    ,这是我需要的。NodeData必须是私有的。关于设计-我不知道。我试图实现简单的DOM结构,而不是不安全的,只使用现有的方法/结构,而不是从头开始创建一切。而
    RefCell
    是我找到的实现可变数据的唯一方法。@RazrFalcon使用
    map
    函数只获取文本:
    Ref::map(self.0.borrow(),|n |&n.text)
    @Arjan谢谢!这正是我想要的。我当前使用Rc的实现之间唯一的区别是我需要两种方法:regular和_mut。据我所知,Ref::map没有性能成本,因为它只是一个包装器,对吗?
    fn borrow(&self) -> Ref<T>
    
    let text = my_node.text();
    println!("the text is {} chars long", text.len());
    my_node.set_text("hi".into());   // boom!