簡體   English   中英

Rust:如何返回對 Rc 的引用<RefCell<HashMap<K, V> &gt; 價值?

[英]Rust: How to return a reference to an Rc<RefCell<HashMap<K, V>> value?

我正在嘗試學習 Rust,但在使用不同的智能指針和其他東西時遇到了一些問題。

這是我的代碼:

pub struct MyMap<T> {
    map: Rc<RefCell<HashMap<String, T>>>,
}

impl <T> MyMap<T> {
    // Not entire sure if it's supposed to be Option<Ref<T>> or something else here.
    pub fn get(&self, key: &str) -> Option<Ref<T>> {
        todo!("What do I do here?")
    }
}

我得到的最接近的是通過搜索 HashMap 兩次:

impl <T> MyMap<T> {
    pub fn get(&self, key: &str) -> Option<Ref<T>> {
        if self.map.borrow().contains_key(key) {
            Some(Ref::map(self.map.borrow(), |m| m.get(key).unwrap()))
        } else {
            None
        }
    }
}

至少可以說這不是很優雅。

我想到了兩個解決方案:

  • 使用不穩定的Ref::filter_map ,它可能會在1.63.0中穩定。
  • 使用上下文管理器模式,它可以繞過整個問題。

filter_map

#![feature(cell_filter_map)]

use std::{
    cell::{Ref, RefCell},
    collections::HashMap,
    rc::Rc,
};

pub struct MyMap<T> {
    map: Rc<RefCell<HashMap<String, T>>>,
}

impl<T> MyMap<T> {
    pub fn get(&self, key: &str) -> Option<Ref<T>> {
        Ref::filter_map(self.map.borrow(), |map| map.get(key)).ok()
    }
}

fn main() {
    let map: MyMap<u32> = MyMap {
        map: Rc::new(RefCell::new(HashMap::from([
            ("meaning".to_string(), 42),
            ("nice".to_string(), 69),
        ]))),
    };

    println!("{:?}", map.get("meaning"));
}
Some(42)

上下文管理器:

這里的想法是,不是返回引用,而是傳入需要該值的操作的閉包。 這完全規避了生命周期問題,因為在執行閉包時, get (或下例中的with_value )內部的變量仍在范圍內。

use std::{cell::RefCell, collections::HashMap, rc::Rc};

pub struct MyMap<T> {
    map: Rc<RefCell<HashMap<String, T>>>,
}

impl<T> MyMap<T> {
    pub fn with_value<F, O>(&self, key: &str, f: F) -> O
    where
        F: FnOnce(Option<&T>) -> O,
    {
        f(self.map.borrow().get(key))
    }
}

fn main() {
    let map: MyMap<u32> = MyMap {
        map: Rc::new(RefCell::new(HashMap::from([
            ("meaning".to_string(), 42),
            ("nice".to_string(), 69),
        ]))),
    };

    map.with_value("meaning", |value| {
        println!("{:?}", value);
    });
}
Some(42)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM