Я думаю, что нашел ответ, но если у кого-то есть лучший ответ, не стесняйтесь писать.Я, очевидно, еще не очень осведомлен об этом, иначе я бы не спросил.
Для полноты: универсальный G
необходим, потому что генераторы похожи на замыкания, а каждое замыкание имеет свой тип (не толькокаждое объявление - также каждое создание), поскольку оно захватывает другую среду.
Как указано Ошибка «Ожидаемый параметр типа» в конструкторе универсальной структуры , первой проблемой было универсальноевведите после impl
.Это означало, что реализация предназначалась для T
, выбранного извне, но вместо этого возвращенное значение Self
имело определенное значение для параметра типа, а именно для генератора.
Что касается его замены,
impl Container<G> where G: Generator<Yield = i32, Return = ()>
Это не работает, потому что хотя G
ограничено (довольно строго), до сих пор никто не отвечает за выбор конкретного G
.
impl Container<_>
Это не работает, потому что вывод типов не работает для реализаций структуры.Что, вероятно, имеет смысл - это не будет логично для чего-либо, кроме «конструкторов».
impl Container<Generator<Yield = i32, Return = ()>>
Это не работает, потому что Generator
являетсяОбъекты trait и trait не имеют размера (тогда как этот параметр типа должен иметь размер).
Размерность может быть решена.Потребовалось немного попыток, и я не уверен, что это идеально, но добавление Box
в реализацию исправило это.Обратите внимание, что Box
не является частью Container
;очевидно, Box<Generator<...>>
также удовлетворяет условию G: Generator<...>
?
I думаю это также значительно уменьшает шансы перемещения генератора, что, как я думаю не должно происходить:
Функция resume
небезопасна, поскольку ее можно использовать в неподвижном генераторе.После такого вызова неподвижный генератор больше не должен двигаться, но компилятор не применяет его.
Полный код:
#![feature(nll)]
#![feature(generators, generator_trait)]
use std::ops::Generator;
struct Container<G>
where
G: Generator<Yield = i32, Return = ()>,
{
generator: G,
}
impl Container<Box<Generator<Yield = i32, Return = ()>>> {
pub fn new() -> Self {
let q = 42;
Container {
generator: Box::new(move || {
yield 1i32 * q;
yield 2i32 * q;
yield 3i32 * q;
}),
}
}
}
fn main() {}
Детская площадка длявыше и пример использования .