Вернуть итератор

Aug 23, 2016 05:36

А между тем, зацените, в nightly rust научились делать вот так:

#![feature(conservative_impl_trait)]

fn numbers() -> impl Iterator {
1 ..
}
Дословно, мы из функции возвращаем некоторый анонимный тип, всё что известно про которого - это то, что он реализует типаж Iterator, ассоциативный тип Item коего установлен в i32Выглядит сумбурно, ( Read more... )

code, anonymous type, rust, programming language, iterator, closures, trait

Leave a comment

swizard December 26 2016, 00:04:24 UTC
Глобально, никакой особой сложности нет. Но конкретно в Rust с подобного рода возвращаемыми значениями есть пара тонкостей:

1) Надо понять, кто будет владельцем объекта. Так как в языке не используется GC, отвественным за уничтожение является владелец (owner) - согласно дизайну языка, у каждого объекта может быть только один владелец (хотя он может меняться).

Так как объект (конкретно в нашем случае это итератор или замыкание) полностью создаётся в пределах контекста функции, и этот контекст будет уничтожен после возврата значения из неё, то единственный вариант передать объект наружу - это сделать т. н. "ownership transferring": отдав владение объектом вовне, человеку, вызывающему функцию. Тогда созданный нами объект должен будет уничтожать уже он (ну, или, в свою очередь передать владение кому-то).

2) Соответственно, в сигнатуре функции должен быть явно указан тип возвращаемого значения: мы же должны получить его во владение. Для объекта, реализующего трейт итератора это сделать не так-то просто, не указав какие-то детали имплементации собственно объекта (подробнее см. http://stackoverflow.com/questions/27535289/correct-way-to-return-an-iterator ), а для замыкания в ряде случаев и вовсе невозможно, так как для них компилятор генерирует уникальный анонимный тип, который используется только для автовыведения типов.

Поэтому раньше нам, обычно, приходилось перемещать объект в heap, и прятать его за box-указатель на trait. В этом случае мы как-бы добирались до объекта через vtable (аналогично virtual-классам в плюсах). Теперь, с помощью синтаксиса "impl trait" мы можем сделать то же самое, но без лишней аллокации и виртуальных методов - типа, полноценная zero-cost абстракция :)

Reply

tancorko December 26 2016, 09:01:02 UTC
"а для замыкания в ряде случаев и вовсе невозможно, так как для них компилятор генерирует уникальный анонимный тип, который используется только для автовыведения типов"

Вот теперь ясно. Спасибо за развернутый ответ.
Осталось в stable дождаться.

Reply


Leave a comment

Up