#rust
Вопрос:
trait Envs {
type Item;
type Iter: Iterator;
fn get_envs(amp;self) -> Self::Iter<Item=Self::Item>;
}
Я пытаюсь реализовать метод, который возвращает переменные среды, но я не мог понять, почему связанный тип не разрешен в черте.
Ответ №1:
trait Envs {
type Item;
type Iter: Iterator<Item = Self::Item>;
fn get_envs(amp;self) -> Self::Iter;
}
Если вы сделаете, как указано выше, это ограничит реализацию признака, чтобы указать Iterator
, с которым связан тип, такой же, как Envs::Item
. Итак, Envs::Item
должно быть так же, как <Envs::Iter as Iterator>::Item
.
Если вам действительно нравится:
trait Envs {
type Item;
type Iter: Iterator;
fn get_envs(amp;self) -> Self::Iter;
}
Это позволило бы разработчику указать Iter
, который не возвращает элементы, такие же, как Envs::Item
. Итак, в данном случае вполне возможно, что Envs::Item
это было i32
, но Envs::Iter
это Iterator
конец String
.
Комментарии:
1. Существует также возможность сделать только метод зависящим от дополнительных требований:
fn get_envs(amp;self) -> Self::Iter where Self::Iter: Iterator<Item = Self::Item>;
. (Не очень полезно в этом случае, но полезно, когда к одному методу предъявляются более высокие требования, чем к остальной части признака, и признак можно использовать без него.)2. Еще один вариант-не беспокоиться об объявлении
Item
в качестве связанного типа, а просто объявитьtype Iter: Iterator;
. Вы все еще можете получить доступ к типу элемента, используяSelf::Iter::Item
, если вам это нужно.
Ответ №2:
Вы можете заставить метод признака возвращать объект признака итератора в штучной упаковке, как показано ниже, если вы хотели, чтобы связанный тип итератора был типом элемента, связанным с вашим признаком.
trait Envs {
type Item;
fn get_envs(amp;self) -> Box<dyn Iterator<Item=amp;Self::Item>>;
}