Rust generics are awesome!
Примерно с това парче мога да парсвам редове от текстов файл към абсолютно всеки тип който имплементира FromStr без да трябва да му напиша типа нито веднъж:
pub fn parse_lines<I, T, E>(input: I) -> Vec<T>
where
I: AsRef<str>,
E: Debug,
T: FromStr<Err = E>,
{
input
.as_ref()
.lines()
.map(|ж| ж.parse())
.collect::<Result<_, _>>()
.unwrap()
}
За сравнения, същото нещо не може да се напише на джава :)
Какво гледаме? Че прекарва generic T от return-а обратно по веригата?
Нещо такова, но не от ретърн-а, ами от извън функцият, но не това е интересното.
Интересното и важното в случая е, че може да се викат методи на конкретния тип през generic параметър-а, и точно това е което не може да се направи на джава, за Цострото не знам, но ще ми е интересно да разбера.
В случая parse() все едно се явява статичен метод на Dog & Cat, и компилатора вика правилния "статичен" метод в зависимост от конкретния тип, нищо че вътре в метода се споменава само интерфейса (FromStr).
Докато в джава няма статични методи в интрефейса - в смисъл има,но те принадлежат на типа на интерфейса, а не на типа на конкретния клас който го имплементира. И поради тази причина не може да се напише такъв generic method.
Примерно такова нещо е невалидно в джава:
interface FromStr{
static FromStr parse(String input);
}
class Cat implements FromStr{
static FromStr parse(String input);
}
class Dog implements FromStr{
static FromStr parse(String input);
}
<T: extends FromStr> T parse_input(String input) {
return T::parse(input);
}