743просмотров
26 февраля 2026 г.
Score: 817
Придумал забавный способ передать список из разных типов в функцию. trait List { type Head; type Tail: List; fn split(self) -> (Self::Head, Option<Self::Tail>);
} При этом трейт должен быть конкретный, для задачи, что бы в Head добавить нужный баунд. В чем тут прикол, ведь так список как бы бесконечный получается, раз Head всегда есть?
В том то и дело, что с точки зрения типов - да, бесконечный.
Только в конце списка Tail = Void, а у Void уже оба Head = Void и Tail = Void.
Сам Void это очевидно enum Void {}, который реализует любые нужный трейты.
То есть это бесконечный список типов, бесконечный хвост которого - пустота.
А List::split просто вернет None хвост в "рантайме". Функция, в которую передали такой список может продолжать делать split, пока хвост - Some(tail).
Ограничение этой конструкции в том, что функция не может делать split в цикле, там же разные типы. Так что она либо делает это рекурсивно, либо фиксированное максимальное количество раз в теле. Ссылка на playground с демонстрацией идеи
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=82105fbaa8d370dec34f00a5900793df