tl; др: это невозможно.
Прежде всего, это недействительно:
struct MyDB {
hash_container: HashMapContainer
}
HashMapContainer
- это черта, но вы пытаетесь использовать ее как тип. Вместо этого вам необходимо (1) ввести параметр типа, ограниченный признаком:
struct MyDB<H: HashMapContainer> {
hash_container: H,
}
Или (2) использовать объект черты, например, в Box
:
struct MyDB {
hash_container: Box<dyn HashMapContainer>,
}
Каждый из этих подходов имеет свои компромиссы. Использование параметра type фиксирует тип к тому, что должно быть известно во время компиляции. Объект признака будет более гибким, поскольку конкретный тип может изменяться во время выполнения, но имеет некоторые последствия для производительности, а также некоторые ограничения для признака и способа его использования.
Поскольку вы хотите выбрать реализацию HashMapContainer
во время выполнения, основываясь на строковом значении, вы должны идти по маршруту объекта черты. Однако, поскольку конкретный тип известен только во время выполнения, связанный тип будет известен только во время выполнения. Это означает, что компилятор не сможет проверять все, что связано с типом.
По сути, ваши комбинированные требования; динамическое изменение реализации признака и опора на связанный тип признака; несовместимы.
Если бы вы могли исправить связанный тип, чтобы он всегда был одинаковым, тогда это может сработать:
struct MyDB {
hash_container: Box<dyn HashMapContainer<Value = SomeType>>,
}
В качестве альтернативы, если вы хотите ограничить реализации черты фиксированным набором известных типов, вы можете закодировать их в перечислении.
Фактический ответ здесь будет зависеть от ваших реальных требований и от того, где вы сможете согнуть их.