gpt4 book ai didi

rust - 在Rust中对 “caching proxy”拥有适当的所有权?

转载 作者:行者123 更新时间:2023-12-03 11:44:06 25 4
gpt4 key购买 nike

我想使用FactoryString构建对象,并具有多个含义:1)实际构建和2)缓存(将内存存储在HashMap中)。问题在于,在#1的情况下,它必须传递所有权,在#2的情况下,HashMap拥有该值,并且只能返回引用。


use std::collections::HashMap;

// product interface
pub trait TProduct {
fn get_title(&self) -> &String;
}

// and concrete impls
pub struct ConcreteProduct1 {
}

impl TProduct for ConcreteProduct1 {
// ...
}

pub struct ConcreteProduct2 {
}

impl TProduct for ConcreteProduct2 {
// ...
}

// factory interface
pub trait TProductFactory {
fn product_from_text(&mut self, text: String) -> Box<dyn TProduct>;
// QUESTION: should it be Box (required for ProductFactory) or &Box (required for ProductCachingProxy)?
}

// actual building factory
pub struct ProductFactory {
}

impl TProductFactory for ProductFactory {
fn product_from_text(&mut self, text: String) -> Box<dyn TProduct> {
//...
// depending on some conditions
Box::new(ConcreteProduct1::from_text(text)); // has to pass the ownership
// or
Box::new(ConcreteProduct2::from_text(text)); // has to pass the ownership
//...
}
}

// caching proxy
trait TProductCache {
fn put(&mut self, text: &String, product: Box<dyn TProduct>);
fn get(&self, text: &String) -> Option<&Box<dyn TProduct>>;
fn clear(&mut self);
}

struct InMemoryProductCache {
map: HashMap<String, Box<dyn TProduct>>
}

impl InMemoryProductCache {
fn new() -> Self {
return InMemoryProductCache {
map: HashMap::new()
}
}
}

impl TProductCache for InMemoryProductCache {
fn put(&mut self, text: &String, product: Box<dyn TProduct>) {
self.map.insert(text.to_string(), product);
}

fn get(&self, text: &String) -> Option<&Box<dyn TProduct>> {
return match self.map.get(text) {
Some(boxed_product) => Some(boxed_product), // have to pass a reference to let it still own the value
None => None
}
}

fn clear(&mut self) {
self.map.clear();
}
}

struct ProductCachingProxy {
product_factory: Box<dyn TProductFactory>,
cache: Box<dyn TProductCache>
}

impl ProductCachingProxy {
fn new_for_factory(product_factory: Box<dyn TProductFactory>, cache: Box<dyn TProductCache>) -> Self {
return ProductCachingProxy {
product_factory,
cache
}
}
}

impl TProductFactory for ProductCachingProxy {
fn product_from_text(&mut self, text: String) -> &Box<dyn TProduct> { // can't pass ownership
let boxed_product = match self.cache.get(&text) {
Some(found_boxed_product) => found_boxed_product,
_ => {
// delegate creation to wrapped TProductFactory impl (`product_factory`)
let boxed_product = self.product_factory.product_from_text(text.clone());
// ... and put to the cache
self.cache.put(&text, boxed_product);
&boxed_product
}
};
return boxed_product;
}
}

//问题:从 Box返回的应该是 &Box(对于ProductFactory是必需的)还是 TProductFactory.fn product_from_text(&mut self, text: String) -> Box<dyn TProduct>;(对于ProductCachingProxy是必需的)?
如果缓存代理返回 Box,如何从引用中创建它而不复制/克隆( TProductCache.get(..))?

最佳答案

Box替换为Rc(如果使用线程,则替换为Arc)。它提供了共享所有权,并为您的两个案例提供了单一签名。另一种选择是使用Cow,它是拥有和借用状态的枚举。

关于rust - 在Rust中对 “caching proxy”拥有适当的所有权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65920550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com