Attualmente sto scrivendo un'API per algoritmi di apprendimento automatico in Rust e mi piacerebbe che un singolo algoritmo genetico, una rete neurale artificiale o una rete bayesiana fornissero più output in modo tale che per le istanze in cui ci possa essere ridondanza, gli algoritmi possono beneficiare l'uno dell'altro. Intendo utilizzarli per produrre molte uscite, quindi la quantità di output non è banalmente piccola.
Vector
In C ++, se volessi restituire più output variabili, probabilmente li aggiungerei ad un vettore passato per riferimento nella funzione, ma ciò è altamente restrittivo perché presuppone che l'utente intenda che i valori vengano inseriti in un vettore, e se hanno bisogno di essere spostati successivamente in qualsiasi altra struttura di dati, si verificheranno alcuni overhead per copiare gli output risultanti.
Tratti
Poiché utilizzo Rust e il sistema dei tratti è pieno di molti tratti che possono essere implementati e implementati per diverse strutture di dati standard, mi chiedo se esiste un tratto che funziona come un iteratore in quanto posso chiamarlo per aggiungere valori a qualsiasi struttura in modo generico evitando al contempo l'overhead utilizzando la monomorfizzazione di Rust.
Chiusure
In alternativa, sto anche pensando di creare un parametro FnMut per passare una chiusura in modo da poter passare questi valori in modo che possano essere consumati comunque desiderati. Anche questo metodo è potente, dal momento che i valori possono essere consumati direttamente se non hanno bisogno di essere inseriti in una struttura dati. Lo svantaggio è che presumo, ma non sono sicuro, il sovraccarico di una chiamata di funzione ogni volta che viene utilizzato questo metodo.
Iteratori
Un altro modo che sto considerando è l'utilizzo degli iteratori di Rust. Penso che dovrebbe essere possibile restituire un iteratore dall'algoritmo di machine learning che elabora pigramente parti dell'algoritmo che sono necessarie per produrre ogni output quando ogni valore è richiesto e poi lo si annulla dall'iteratore quando next () viene chiamato su di esso. Penso che questo metodo dovrebbe fornire la massima flessibilità con le massime prestazioni, ma questo sembra anche che potrebbe essere un egregio abuso degli iteratori di Rust, anche se vedo cose simili nella libreria standard. Penso che dovrebbe essere possibile implementare l'iteratore in modo tale da poter memorizzare tutti gli stati intermedi nel calcolo all'interno della struttura iteratore. Ciò potrebbe causare alcuni problemi con il prestito dalla struttura dell'algoritmo di apprendimento a patto che l'iteratore sia in ambito, ma non penso che questo sia un problema.
Quale di questi metodi è più utile per la programmazione generica e si adatta alle migliori pratiche di Rust? Esistono altri metodi che non ritengo possano funzionare meglio o fornire un supporto migliore per la programmazione generica? Inoltre, qualsiasi critica o consiglio su come migliorare questi metodi è ben accolto e accettato.