英文:
Make IntoIterator trait implementation lifetime-dynamic
问题
Here's the translated code without the translation of code comments:
我有这段代码可以运行:
```rust
impl<T> IntoIterator for Range<T>
where
T: Display + PartialOrd + 'static,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
Rev<RangeInclusive<T>>: Iterator<Item = T>,
{
type Item = T;
type IntoIter = Box<dyn Iterator<Item = T>>;
fn into_iter(self) -> Self::IntoIter {
if self.start > self.end {
Box::new((self.start..=self.end).rev())
} else {
Box::new(self.start..=self.end)
}
}
}
我想重构它以使用动态生命周期而不是 'static
。但是,我无法弄清楚如何做到这一点,因为我似乎总是遇到 unconstrained lifetime parameter 错误:
impl<'a, T> IntoIterator for Range<T>
where
T: Display + PartialOrd + 'a,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
Rev<RangeInclusive<T>>: Iterator<Item = T>,
{
type Item = T;
type IntoIter = Box<dyn Iterator<Item = T> + 'a>;
fn into_iter(self) -> Self::IntoIter {
if self.start > self.end {
Box::new((self.start..=self.end).rev())
} else {
Box::new(self.start..=self.end)
}
}
}
在这里是否可能使用动态生命周期?
其他类型
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Range<T>
where
T: Display + PartialEq,
{
start: T,
end: T,
}
impl<T> Range<T>
where
T: Display + PartialEq,
{
pub fn new(start: T, end: T) -> Self {
Self { start, end }
}
}
错误
error[E0207]: the lifetime parameter 'a is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:56:6
|
56 | impl<'a, T> IntoIterator for Range<T>
| ^^ unconstrained lifetime parameter
<details>
<summary>英文:</summary>
I have this code which works:
impl<T> IntoIterator for Range<T>
where
T: Display + PartialOrd + 'static,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
Rev<RangeInclusive<T>>: Iterator<Item = T>,
{
type Item = T;
type IntoIter = Box<dyn Iterator<Item = T>>;
fn into_iter(self) -> Self::IntoIter {
if self.start > self.end {
Box::new((self.start..=self.end).rev())
} else {
Box::new(self.start..=self.end)
}
}
}
I'd like to refactor it to use a dynamic lifetime instead of `'static`.
However, I cannot figure out how to do this, since I always seem to run into the *unconstrained lifetime parameter* error:
impl<'a, T> IntoIterator for Range<T>
where
T: Display + PartialOrd + 'a,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
Rev<RangeInclusive<T>>: Iterator<Item = T>,
{
type Item = T;
type IntoIter = Box<dyn Iterator<Item = T> + 'a>;
fn into_iter(self) -> Self::IntoIter {
if self.start > self.end {
Box::new((self.start..=self.end).rev())
} else {
Box::new(self.start..=self.end)
}
}
}
Is it possible, do use a dynamic lifetime here?
**Orther types**
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Range<T>
where
T: Display + PartialEq,
{
start: T,
end: T,
}
impl<T> Range<T>
where
T: Display + PartialEq,
{
pub fn new(start: T, end: T) -> Self {
Self { start, end }
}
}
**Error**
error[E0207]: the lifetime parameter 'a
is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:56:6
|
56 | impl<'a, T> IntoIterator for Range<T>
| ^^ unconstrained lifetime parameter
</details>
# 答案1
**得分**: 1
你可以使用 [`either`](https://docs.rs/either/latest/either/enum.Either.html) 或 [`itertools`](https://docs.rs/itertools/latest/itertools/enum.Either.html) 中的 `Either` 代替 `Box<dyn Iterator>` 来保存两个迭代器中的一个,而不会引起 `dyn Iterator` 引发的生命周期问题。以下是相应的Rust代码:
```rust
impl<T> IntoIterator for Range<T>
where
T: Display + PartialOrd + 'static,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
{
type Item = T;
type IntoIter = Either<Rev<RangeInclusive<T>>, RangeInclusive<T>>;
fn into_iter(self) -> Self::IntoIter {
if self.start > self.end {
Either::Left((self.start..=self.end).rev())
} else {
Either::Right(self.start..=self.end)
}
}
}
英文:
You can use Either
from either
or itertools
instead of Box<dyn Iterator>
to hold one of two iterators, without the lifetime problems caused by dyn Iterator
:
impl<T> IntoIterator for Range<T>
where
T: Display + PartialOrd + 'static,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
{
type Item = T;
type IntoIter = Either<Rev<RangeInclusive<T>>, RangeInclusive<T>>;
fn into_iter(self) -> Self::IntoIter {
if self.start > self.end {
Either::Left((self.start..=self.end).rev())
} else {
Either::Right(self.start..=self.end)
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论