Estou escrevendo um aplicativo de gerenciamento de tarefas de linha de comando para aprender Rust.
Até agora tenho um sqllite e uma fonte de dados de memória.
pub struct TaskManager {
source: Datasource, // here rustc complains
}
O gerente tem uma referência a um Datasource
, que é uma característica:
pub trait Datasource {
type Settings;
fn start(&self) -> Result<bool>;
}
O Main lê argumentos CLI e decide com base neles qual fonte de dados deve ser instanciada.
No entanto, Rust me diz
"- rustc: o valor do tipo associado
Settings
emsource::Datasource
deve ser especificado [E0191]"
Entendo que os tipos devem ser especificados em tempo de compilação, e ambas as fontes até agora têm seus tipos especificados.
impl Datasource for SqlLiteDataSource {
type Settings = SqlLiteSettings;
}
impl Datasource for MemoryDataSource {
type Settings = MemorySettings;
}
E ao analisar os argumentos cli, todos os braços são avaliados:
pub fn new(datasource: Datasources) -> Self {
let ds: Datasource = match datasource {
Datasources::SqlLite { path } => SqlLiteDataSource::new(path.to_string()),
_ => MemoryDataSource::new(),
};
}
Na verdade, o rustc também está reclamando aqui com o mesmo erro.
A ideia era que cada implementação concreta tivesse suas próprias configurações. Como posso então atribuir uma variável de trait genérica ao TaskManager
, para que um backend conclua o gerenciamento de tarefas dependendo da fonte fornecida?
O problema é que você não pode colocar um trait com um tipo diretamente em uma struct. Você precisaria usar um trait Boxed dentro do TaskManager, porque o compilador Rust precisa saber um tipo específico (nesse caso, Settings) para o Datasource. Altere a linha
source: Datasource
para definir o trait Boxed com um tipo de Settings padrão ou outro trait boxed. Se você tiver um tipo de Settings padrão específico para o qual você pode defini-lo para compilação, você pode apenas alterar a linha parasource: Box<dyn Datasource<Settings=ChosenType>>
ou você pode definir Settings para um trait boxed também usando a linhasource: Box<dyn Datasource<Settings=Box<dyn Settings>>>
Isso esclarecerá ao compilador Rust um tipo especificado para o atributo Datasource dentro da estrutura TaskManager.