Николай качи първо решение на 27.12.2017 10:10 (преди над 7 години)
Радвам се, че се усети за формата, че предизвикателствата нямат коментари :)
Иначе, няма проблеми да е просто решение, както казахме, но е доста добра идея да го изтестваш с някакви по-особени примери, да видиш дали работи правилно :). Конкретно extract_words
може би има edge case-ове, с които не се справя супер добре.
Благодаря за загрижеността, относно формите.
Относно edge case-а, един който намерих е, че няма да може да намира думи с тирета. Примери: по-голям
, най-интересен
и тн.
Смятам да го оправя с използването на WordIterator
, но когато започнах да го пиша стигнах до следния момент:
pub struct WordIterator<'a> {
chars: std::str::Chars<'a>
}
...
impl<'a> Iterator for WordIterator<'a> {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
self.chars = self.chars.skip_while(|c| !c.is_alphabetic());
...
}
}
Това е невалидно, тъй като self.chars
очаква std::str::Chars, докато аз се опитвам да му дам std::iter::SkipWhile
.
Няма имплементация за into
(Тъй като, ако не се лъжа, типа се получава std::iter::SkipWhile<std::str::Chars>
) и ми се налага да правя:
self.chars = self.chars.skip_while(|c| !c.is_alphabetic()).collect::<String>().chars();
което не мисля, че е напълно коректно. Има ли някакъв вграден начин за преобразуване на итератори, или съм тръгнал изцяло в грешна посока?
Не, това е проблем, на който удари и някой друг -- няма конкретен общ тип, до който може да се "сведе" един итератор. Няма "наследяване" реално, това се имплементира с trait-ове. Но конкретния тип трябва да е същия. На теория, може да се държи Box<Iterator>
, което обаче би изисквало алокация на heap-а, и едно ниво на индирекция на всяко викане на next
, така че не бих го приел като валидно решение за целите на бонус точките.
Ако минеш през collect().chars()
, единственото, което ще постигнеш, е да го конвертираш в наново-алокиран низ, и после да вземеш неговите символи. Дори не съм сигурен дали това ще проработи в случая, понеже низа би бил временен, и би взел reference към току-що деструктиран низ.
Съветвам те да направиш крачка назад и да пробваш различна тактика. Трябва някак да сменяш вътрешното състояние, но то трябва да си остане същия тип. Има няколко различни посоки (включително една-две измислена от колегите ти, които не бях се сетил :)), но трябва да си харесаш една, която работи :). Разгледай документациите на str
, Chars
, char
, има какво да намериш. Не се притеснявай да пробваш и с "глупава" итерация, не винаги е по-лесно да композираш неща :).