Обобщения Rust отличаются от шаблонов C ++. Существуют веские причины, по которым они различаются, например, улучшенные отчеты об ошибках и более быстрая компиляция.
В C ++ шаблоны (если мы упрощаем) не проверяются на начальной стадии вызова, скорее шаблон продолжает расширяться до это либо успешно, либо выполняется операция, которая не поддерживается указанным типом c.
В Rust типы проверяются немедленно. Спецификация должна быть предоставлена заранее, что означает, что любая ошибка обнаруживается на сайте вызова, в отличие от глубокого расширения шаблона.
В вашем конкретном примере c предполагается, что каждый T
должен иметь поля key
и hits
, но T
может быть любым, начиная от примитивных типов до непубличных c структур, которые не имеют полей key
или hits
.
The Rust способ сделать что-то - объявить черту и использовать ее, чтобы указать, что у типа есть определенная функция конструктора для вас. В этом контексте черта будет абстракцией с нулевой стоимостью из-за полиморфизма stati c.
trait StringConstructable {
fn new(string: String) -> Self;
}
struct Test {
key: String,
hits: usize
}
impl StringConstructable for Test {
fn new(string: String) -> Self {
Test {
key: string,
hits: 0
}
}
}
fn test<T: StringConstructable>() -> T {
T::new("test".to_string())
}
ссылка на игровую площадку
Или реализовать и потребовать From<String>
для вашей T
.
struct Test {
key: String,
hits: usize
}
impl From<String> for Test {
fn from(string: String) -> Test {
Test {
key: string,
hits: 0
}
}
}
fn test<T: From<String>>() -> T {
T::from("test".to_string())
}
ссылка на игровую площадку