Ответ 1
Есть одна вещь, которую легко упустить из виду: если у вас есть черта Bar
и вы хотите иметь объект в штучной упаковке Box<dyn Bar>
, компилятор автоматически добавляет ограничение времени жизни 'static
(как указано в RFC 599). Это означает, что Box<dyn Bar>
и Box<dyn Bar + 'static>
эквивалентны!
В вашем случае компилятор автоматически добавляет статическую границу, так что это...
fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>>
... эквивалентно этому:
fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'static>
Теперь правила выбора времени жизни включаются и "соединяют" два интервала времени жизни, так что приведенный выше код эквивалентен:
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'static>
Но тип Iter<'a, Foo>
(определенный тип итератора для Vec<Foo>
), очевидно, не удовлетворяет границе 'static
(потому что он заимствует Vec<Foo>
)! Таким образом, мы должны сказать компилятору, что мы не хотим привязку по умолчанию 'static
, указав нашу собственную границу времени жизни:
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'a>
Теперь компилятор знает, что объект признака действителен только на время жизни 'a
. Обратите внимание, что нам не нужно явно аннотировать время жизни ассоциированного типа Item
! Правила пожизненного выбора заботятся об этом.