C++ è stato criticato perché manca la compilazione separata di modelli. I modelli C++ sono compilati per (praticamente) ogni istanza. Qual è lo stato delle cose per Rust riguardo alla compilazione separata dei generici? La mia comprensione è che si comporta come C++ eccetto che le istanze vengono memorizzate nella cache durante la compilazione di ciascuna cassa. È corretto ?Compilazione separata per generici in Rust
risposta
Per quanto ne so, i farmaci generici sono memorizzati in qualche forma serializzata nella cassa in cui sono definiti. Quando vengono utilizzati in un'altra cassa (libreria o binario) vengono istanziati da questa forma serializzata. Quindi sono monomorfizzati allo stesso modo dei modelli C++ ma viene evitato il sovraccarico di ripetuti parsing di codice non necessario.
Dalla documentazione del tutorial:
Il compilatore Rust compila funzioni generiche in modo molto efficiente da loro monomorphizing. La monomorfizzazione è un nome di fantasia per un'idea semplice: genera una copia separata di ogni funzione generica in ogni sito di chiamata, una copia specializzata per i tipi di argomento e può quindi essere ottimizzata specificamente per loro. A tale riguardo, i generici di Rust hanno caratteristiche di performance simili a modelli C++. http://doc.rust-lang.org/0.11.0/tutorial.html#generics
EDIT: questo non ha davvero rispondere alla tua domanda, vero?
Quel testo è esattamente il motivo per cui ho congetturato che è lo stesso del C++. Mi piacerebbe sentire qualcosa di più esplicito, però. – Gepp
I tipi e le funzioni generici sono monomorfizzati. Tuttavia, è possibile utilizzare tratti senza generici.
Questa è una funzione generica. Sarà monomorfizzato.
fn get_length<T: Collection>(collection: &T) -> uint {
collection.len()
}
Questa è una funzione non generico equivalente. Solo una copia di questa funzione sarà inclusa nel file binario.
fn get_length(collection: &Collection) -> uint {
collection.len()
}
noti che non abbiamo potuto fare una funzione che riceve un Collection
per valore, perché Collection
è un tratto, e quindi non ha dimensione specifica. In questo caso è richiesta una funzione generica.
Ci sono alcune cose che non si possono fare con i generici e alcune cose che non si possono fare con i riferimenti di tratto. Con riferimenti tratti, hai bisogno di un tratto, ovviamente. Con i generici, non è possibile avere un vettore di raccolte in cui le raccolte sono di diverso tipo (ad esempio non è possibile inserire un Vec<int>
e un String
in quel vettore), ma è possibile utilizzare i riferimenti tratti: a e può contenere uno a &String
.
- 1. Rust cancella i tipi generici o no?
- 2. Compilazione condizionale di metodi generici
- 3. Generici bizzarici errore di compilazione
- 4. generici Java errore di compilazione
- 5. GHC Valutazione parziale e compilazione separata
- 6. Tipi di modulo OCaml e compilazione separata
- 7. Eseguire la compilazione separata dei documenti Latex
- 8. Applicazione di frontend separata - strategie di compilazione e implementazione
- 9. Ricerca separata per frammenti
- 10. Perché Rust inserisce a :: before i parametri in generici a volte?
- 11. separata marmellata per WebView in OS X
- 12. Implementare l'aritmetica in generici?
- 13. Sessione separata per ogni finestra
- 14. Npm Installa DevDependencies in una directory separata
- 15. compilazione di sphinx separata e directory di origine per il controllo della versione
- 16. Aliasing rigoroso in Rust?
- 17. API UDP in Rust
- 18. TabItem in XAML separata
- 19. Impossibile compilare Rust
- 20. rendere .o file nella cartella separata in compilazione del kernel linux
- 21. "Jump to definition" in Rust
- 22. Strutture dati ricorsive in Rust
- 23. iterazione annidata in macro Rust
- 24. Servizio WCF in Assemblea separata
- 25. Struttura pubblica/privata in Rust
- 26. Cos'è # [warn (unstable)] in Rust?
- 27. MFMailComposeViewController in una classe separata
- 28. Generici di puntatori tramite `mem :: transmute()`
- 29. Equivalenti algoritmi intrusivi in Rust
- 30. Oggetti e classi in Rust
Sono un po 'confuso su dove i modelli si adattano in C++, ma in Rust dove sono interessate le macro è possibile ottenere il modulo espanso con '--pretty expanded'. Ma non i generici. –
In realtà, il vero problema in C++ non è che i template siano compilati per ogni istanza: i compilatori intelligenti eseguono la memoizzazione e hanno una cache di un numero di istanze "precompilate" di un modello per un determinato set di tipi/valori. Il problema principale è * compilazione separata * combinata con '# include', il modello deve essere presente nelle intestazioni, quindi viene analizzato inutilmente in ogni singola unità di traduzione indipendentemente dal fatto che lo utilizzi o meno. Questo problema scomparirà con i moduli (forse C++ 17). –