Открыть список
Как стать автором
Обновить

Комментарии 10

Спасибо за доходчивое объяснение. На днях как раз задавался этим вопросом и читал, что пишут на форумах по этой теме. Эта статья показалась понятнее того, что я видел до этого.
Классная статья. Очень доходчиво объяснено. Хотелось бы побольше таких статей по Rust.
Можно по futures такую же, хотя это уже не сам язык, а его библиотека. Хотя у Rust документировано все классно на оф. сайте. Но для закрепления такое — самое то.
По futures наверно рановато писать, пусть стабилизируют там всё. А вот сделать хороший обзор библиотек навроде Rayon и Crossbeam, наверно, не помешает.
Хотелось бы еще и разбора Lifetime в раст, для новичков. =х
Кажется, что уж по лайфтаймам-то точно много всего написано, это ж основы. В том же растбуке вполне себе доходчиво, кмк.

С итератором — не самый лучший пример, во многих языках итератор сделан именно как Iterator<T> и никаких проблем этим нет. Тип T тут хоть и указывается вроде как внешним кодом, но реально точно так же задаётся реализацией, ведь только реализация решает какие трейты она реализует. А реализация двух итераторов и неоднозначный next — это выдуманная проблема, так просто не надо делать и всё.


Куда интереснее дело обстоит с вскользь упомянутыми коллекциями! Тот же трейт IntoIterator (называемый в Java Iterable, а в C# — IEnumerable), при попытке реализовать его как IntoIterator<T>, начинает требовать динамической диспетчеризации для итератора. В принципе, его можно было бы реализовать и как IntoIterator<T, TIter: Iterator<T>> — но это уже выглядит не так красиво, плюс ограничение TIter: Iterator<T> пришлось бы дублировать при каждом упоминании IntoIterator.

Хотел было ответить, что можно же объявить метод в трейте IntoIterator<T> как fn into_iter(self) -> impl Iterator<T>; но тут внезапно осознал, что impl Trait не поддерживается для методов трейта. Так что да, вы правы, спасибо за ценное дополнение.

никаких проблем этим нет

Ну как нет, проблема именно в отсутствии гарантий неоднозначности, что затрудняет вывод типов. И потом у вас получаются всякие functional dependencies и injective type families.

А разве IntoIter — это аналог IEnumerable<T>? Насколько я помню, IEnumerable<T> является наиболее абстрактным интерфейсом перечисляемой неизменяемой коллекции. А трейт IntoIter забирает владение объектом. Что, вроде как, не позволяет писать такое:


fn foo<T>(collection: &AbstractCollection<T>) {...}

// do something with my_collection
foo(my_collection)
// do something with my_collection

А реализация абстрактного трейта коллекций требует, вроде как, HKT. Поправьте меня, если я не прав.

Различия в протоколе Iterator/IntoIterator невыразимы за пределами Rust, а потому IEnumerable<> является аналогом обоих трейтов. Я говорил про IntoIterator лишь потому, что именно этот трейт упомянул автор поста.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.