Qual é a maneira mais genérica de fornecer uma quantidade variável de saídas de uma função Rust?

5

Atualmente, estou escrevendo uma API para algoritmos de aprendizado de máquina em Rust e gostaria que um único algoritmo genético, rede neural artificial ou rede bayesiana fornecesse várias saídas para que, em instâncias em que houvesse redundância, os algoritmos pudessem beneficiar um do outro. Eu pretendo usá-los para produzir muitas saídas, então a quantidade de saídas não é trivialmente pequena.

Vector

Em C ++, se eu quisesse retornar múltiplas saídas de variáveis, eu provavelmente as adicionaria a um vetor passado por referência na função, mas isso é altamente restritivo porque assume que o usuário pretende que os valores sejam colocados em um vetor, e se eles precisarem ser movidos para qualquer outra estrutura de dados depois, então alguma sobrecarga será incorrida para copiar as saídas resultantes.

Traços

Como estou usando o Rust e o sistema de características está repleto de muitas características que podem ser implementadas e implementadas em várias estruturas de dados padrão, estou querendo saber se existe um traço que funcione como um iterador no qual eu possa chamá-lo para adicionar valores a qualquer estrutura de uma maneira genérica, evitando também sobrecarga usando a monomorfização de Rust.

Encerramentos

Como alternativa, também estou pensando em fazer um parâmetro FnMut para passar um fechamento que eu possa passar esses valores para que eles possam ser consumidos no entanto desejado. Esse método também é poderoso, já que os valores podem ser consumidos diretamente se não precisarem ser colocados em uma estrutura de dados. A desvantagem é que eu suponho, mas não tenho certeza, existe a sobrecarga de uma chamada de função toda vez que esse método é usado.

Iteradores

Outra maneira que estou considerando é usar os iteradores de Rust. Eu acho que deveria ser possível retornar um iterador do algoritmo de aprendizado de máquina que processa lentamente partes do algoritmo que são necessárias para produzir cada saída conforme cada valor é solicitado e, em seguida, reproduzi-lo no iterador quando next () é chamado. Eu acho que este método deve fornecer a maior flexibilidade com o mais alto desempenho, mas isso também parece que pode ser um abuso notório de iteradores Rust, embora eu veja coisas semelhantes na biblioteca padrão. Eu acho que deveria ser possível implementar o iterador de tal forma que eu possa armazenar todos os estados intermediários em computação dentro da estrutura do iterador. Isso pode causar alguns problemas com o empréstimo da estrutura do algoritmo de aprendizado, desde que o iterador esteja no escopo, mas não acho que isso seja um problema.

Qual desses métodos é mais útil para programação genérica e se encaixa nas melhores práticas da Rust? Existem outros métodos que não estou considerando que possam ter um melhor desempenho ou oferecer melhor suporte para programação genérica? Além disso, qualquer crítica ou conselho sobre como melhorar esses métodos é bem-vinda e aceita de bom grado.

    
por vadix 09.11.2015 / 16:04
fonte

1 resposta

3

Eu não acho que o uso de iteradores que você propõe seja um abuso de iteradores. É perfeitamente aceitável que os iteradores realizem cálculos e que eles tenham quantidades significativas de estado. O Rust tem muitas ferramentas internas para manipular e compor iteradores, portanto, essa é provavelmente a maneira mais fácil para seus usuários.

    
por 22.03.2016 / 17:35
fonte