C ++ подвергся критике за отсутствие отдельной компиляции шаблонов. Шаблоны C ++ компилируются (практически) для каждого экземпляра. Как обстоят дела с Rust в отношении отдельной компиляции дженериков? Насколько я понимаю, он ведет себя как C ++, за исключением того, что экземпляры кэшируются во время компиляции каждого ящика. Это верно ?
Насколько я знаю, дженерики хранятся в некотором сериализованном виде в ящике, где они определены. При использовании в другом ящике (библиотечном или двоичном) они создаются из этой сериализованной формы. Таким образом, они мономорфизируются так же, как и шаблоны C ++, но исключаются накладные расходы на повторный анализ ненужного кода.
Из учебного документа:
Компилятор Rust очень эффективно компилирует обобщенные функции, мономорфизируя их. Мономорфизация — причудливое имя для простой идеи: создайте отдельную копию каждой универсальной функции на каждом сайте вызова, копию, которая специализирована для типов аргументов и, таким образом, может быть оптимизирована специально для них. В этом отношении дженерики Rust имеют схожие характеристики производительности с шаблонами C ++.
http://doc.rust-lang.org/0.11.0/tutorial.html#generics
РЕДАКТИРОВАТЬ: это действительно не ответило на ваш вопрос, не так ли?
Общие типы и функции мономорфизированы. Тем не менее, можно использовать черты без дженериков.
Это общая функция. Это будет мономорфизировано.
fn get_length<T: Collection>(collection: &T) -> uint {
collection.len()
}
Это эквивалентная неуниверсальная функция. Только одна копия этой функции будет включена в двоичный файл.
fn get_length(collection: &Collection) -> uint {
collection.len()
}
Обратите внимание, что мы не могли сделать функцию, которая получает Collection
по стоимости, потому что Collection
это черта, и, следовательно, он не имеет определенного размера. В этом случае требуется общая функция.
Есть некоторые вещи, которые вы не можете сделать с генериками, и некоторые вещи, которые вы не можете сделать с ссылками на черты. Очевидно, что с ссылками на черты вам нужна черта. С дженериками у вас не может быть вектора коллекций, где коллекции бывают разных типов (например, вы не можете поместить Vec<int>
и String
в этом векторе), но вы можете с чертами ссылки: Vec<&Collection>
может содержать &Vec<int>
и &String
,