Generics 使用关联类型的特征的结构成员

Generics 使用关联类型的特征的结构成员,generics,hashmap,rust,Generics,Hashmap,Rust,我有一个跟进问题: 假设我想使用HashMapContainer(与前一个问题的第一个答案中定义的相同)作为另一个结构中的成员(我们称之为MyDB)在MyDB构造函数中,我想决定是将此成员构造为hashmapcontainermpl1还是hashmapcontainermpl2。我不想将MyDB定义为模板(例如MyDB),因为MyDB用户不关心HashMap的值(MyDB构造函数将决定该值)。实现这一点的正确方法是什么 下面是我想要实现的示例代码(它没有编译): pub trait HashMa

我有一个跟进问题:

假设我想使用
HashMapContainer
(与前一个问题的第一个答案中定义的相同)作为另一个结构中的成员(我们称之为
MyDB
)在
MyDB
构造函数中,我想决定是将此成员构造为
hashmapcontainermpl1
还是
hashmapcontainermpl2
。我不想将
MyDB
定义为模板(例如
MyDB
),因为
MyDB
用户不关心
HashMap
的值(
MyDB
构造函数将决定该值)。实现这一点的正确方法是什么

下面是我想要实现的示例代码(它没有编译):

pub trait HashMapContainer{
类型值;
fn获取散列映射(&self)->&HashMap;
fn get_hash_map_mut(&mut self)->&mut HashMap;
}
结构MyDB{
hash_容器:HashMapContainer
}
impl MyDB{
pub fn new(哈希值类型:&str)->MyDB{
//具有将hash_container设置为
//HashMapContainerMPL1或HashMapContainerMPL2
//根据哈希值类型
}
发布fn计数键(&self)->使用{
self.hash\u container.get\u hash\u map().len()
}
}
fn main(){
设db=MyDB::new();
println!((“键计数:{}”,db.count_keys());
}

tl;医生:这是不可能的。

首先,这是无效的:

struct MyDB {
    hash_container: HashMapContainer
}
HashMapContainer
是一种特性,但您正试图将其用作类型。相反,您需要(1)引入一个类型参数,该参数受trait的约束:

struct MyDB<H: HashMapContainer> {
    hash_container: H,
}
每种方法都有不同的权衡。使用type参数将把类型固定为编译时必须知道的内容。trait对象将更加灵活,因为具体类型可以在运行时更改,但对trait及其使用方式有一些性能影响和限制

由于要在运行时根据字符串值选择
HashMapContainer
的实现,因此必须使用trait对象路由。但是,由于具体类型仅在运行时已知,因此关联类型也仅在运行时已知。这意味着编译器将无法对涉及关联类型的任何内容进行类型检查

基本上,您的组合需求;动态地改变特征实现并依赖于特征的关联类型;两者不相容

如果您可以修复关联的类型,使其始终保持不变,那么这可能会起作用:

struct MyDB {
    hash_container: Box<dyn HashMapContainer<Value = SomeType>>,
}
struct MyDB{
hash_容器:Box,
}
或者,如果您愿意将trait的实现限制为一组固定的已知类型,那么您可以在枚举中对它们进行编码


这里的实际答案将取决于您的实际需求,以及您能够在哪里弯曲它们。

tl;医生:这是不可能的。

首先,这是无效的:

struct MyDB {
    hash_container: HashMapContainer
}
HashMapContainer
是一种特性,但您正试图将其用作类型。相反,您需要(1)引入一个类型参数,该参数受trait的约束:

struct MyDB<H: HashMapContainer> {
    hash_container: H,
}
每种方法都有不同的权衡。使用type参数将把类型固定为编译时必须知道的内容。trait对象将更加灵活,因为具体类型可以在运行时更改,但对trait及其使用方式有一些性能影响和限制

由于要在运行时根据字符串值选择
HashMapContainer
的实现,因此必须使用trait对象路由。但是,由于具体类型仅在运行时已知,因此关联类型也仅在运行时已知。这意味着编译器将无法对涉及关联类型的任何内容进行类型检查

基本上,您的组合需求;动态地改变特征实现并依赖于特征的关联类型;两者不相容

如果您可以修复关联的类型,使其始终保持不变,那么这可能会起作用:

struct MyDB {
    hash_container: Box<dyn HashMapContainer<Value = SomeType>>,
}
struct MyDB{
hash_容器:Box,
}
或者,如果您愿意将trait的实现限制为一组固定的已知类型,那么您可以在枚举中对它们进行编码


这里的实际答案将取决于您的实际需求以及您能够将它们弯曲到哪里。

相关:此链接确实相关,但不能解决定义结构成员的问题,该结构成员是与相关类型相关的特征:此链接确实相关,但不能解决定义结构成员的问题,该结构成员是特征与相关类型谢谢你的回答!假设我想按照建议(1)将类型参数引入
MyDB
,我将如何实现
MyDB
的构造函数?(例如
MyDB::new()
)谢谢您的回答!假设我想按照建议(1)将类型参数引入
MyDB
,我将如何实现
MyDB
的构造函数?(例如
MyDB::new()