我有这个代码
use std::iter::Step;
fn main() {
for i in mkiter(25, 20) {
println!("{}", i);
}
for i in mkiter(10, 23) {
println!("{}", i);
}
}
fn mkiter<T>(start: T, end: T) -> Box<dyn Iterator<Item = T>>
where
T: Step,
{
if start > end {
Box::new((end..=start).rev())
} else {
Box::new(start..=end)
}
}
Run Code Online (Sandbox Code Playgroud)
但是,编译器告诉我我正在使用不稳定的功能:
error[E0658]: use of unstable library feature 'step_trait': recently redesigned
--> main.rs:1:5
|
1 | use std::iter::Step;
| ^^^^^^^^^^^^^^^
|
= note: see issue #42168 <https://github.com/rust-lang/rust/issues/42168> for more information
error[E0658]: use of unstable library feature 'step_trait': recently redesigned
--> main.rs:13:10
|
13 | where T: Step
| ^^^^
|
= note: see issue #42168 <https://github.com/rust-lang/rust/issues/42168> for more information
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
Run Code Online (Sandbox Code Playgroud)
但是当我移除特质限制时...
fn main() {
for i in mkiter(25, 20) {
println!("{}", i);
}
for i in mkiter(10, 23) {
println!("{}", i);
}
}
fn mkiter<T>(start: T, end: T) -> Box<dyn Iterator<Item = T>> {
if start > end {
Box::new((end..=start).rev())
} else {
Box::new(start..=end)
}
}
Run Code Online (Sandbox Code Playgroud)
...它要我添加它,这让我很困惑:
error[E0369]: binary operation `>` cannot be applied to type `T`
--> main.rs:11:14
|
11 | if start > end {
| ----- ^ --- T
| T
|
help: consider restricting type parameter `T`
|
10 | fn mkiter<T: std::cmp::PartialOrd>(start: T, end: T) -> Box<dyn Iterator<Item = T>> {
| ++++++++++++++++++++++
error[E0599]: the method `rev` exists for struct `RangeInclusive<T>`, but its trait bounds were not satisfied
--> main.rs:12:32
|
12 | Box::new((end..=start).rev())
| ^^^ method cannot be called on `RangeInclusive<T>` due to unsatisfied trait bounds
|
::: /home/rne/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/range.rs:345:1
|
345 | pub struct RangeInclusive<Idx> {
| ------------------------------ doesn't satisfy `RangeInclusive<T>: Iterator`
|
= note: the following trait bounds were not satisfied:
`T: Step`
which is required by `RangeInclusive<T>: Iterator`
`RangeInclusive<T>: Iterator`
which is required by `&mut RangeInclusive<T>: Iterator`
help: consider restricting the type parameter to satisfy the trait bound
|
10 | fn mkiter<T>(start: T, end: T) -> Box<dyn Iterator<Item = T>> where T: Step {
| +++++++++++++
error[E0277]: the trait bound `T: Step` is not satisfied
--> main.rs:14:9
|
14 | Box::new(start..=end)
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Step` is not implemented for `T`
|
= note: required for `RangeInclusive<T>` to implement `Iterator`
= note: required for the cast from `RangeInclusive<T>` to the object type `dyn Iterator<Item = T>`
help: consider restricting type parameter `T`
|
10 | fn mkiter<T: std::iter::Step>(start: T, end: T) -> Box<dyn Iterator<Item = T>> {
| +++++++++++++++++
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0369, E0599.
For more information about an error, try `rustc --explain E0277`.
Run Code Online (Sandbox Code Playgroud)
如何正确实现一个函数,该函数分别为稳定 Rust 中的泛型(整数)类型返回一个RangeInclusive或其迭代器?Rev
# rustc --version 2023-05-24 03:34:14
rustc 1.69.0 (84c898d65 2023-04-16)
# rustup update stable 2023-05-24 03:34:04
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
stable-x86_64-unknown-linux-gnu unchanged - rustc 1.69.0 (84c898d65 2023-04-16)
info: self-update is disabled for this build of rustup
info: any updates to rustup will need to be fetched with your system package manager
Run Code Online (Sandbox Code Playgroud)
要求这T: Step只是达到目的的一种手段,你实际上并不关心是否T实现Step,你只关心它RangeInclusive<T>是一个生成的迭代器T。你可以准确地表达这一点:
fn mkiter<T>(start: T, end: T) -> Box<dyn Iterator<Item = T>>
where
RangeInclusive<T>: Iterator<Item = T>,
...
Run Code Online (Sandbox Code Playgroud)
编译器仍然抱怨Tand Step,但这只是因为您也需要遵循相同的原则才能.rev()通过约束 on 来工作DoubleEndedIterator:
fn mkiter<T>(start: T, end: T) -> Box<dyn Iterator<Item = T>>
where
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
...
Run Code Online (Sandbox Code Playgroud)
然后就剩下一些未解决的问题,例如添加T: PartialOrdsostart > end有效,并添加生命周期以绕过'static默认返回Box<dyn ...>. 这是最终的代码:
fn mkiter<'a, T: 'a>(start: T, end: T) -> Box<dyn Iterator<Item = T> + 'a>
where
T: PartialOrd,
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
{
if start > end {
Box::new((end..=start).rev())
} else {
Box::new(start..=end)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
119 次 |
| 最近记录: |