我试图通过在一个小日历项目上工作来教自己锈。Rust:如何从函数返回一个迭代器并使用它?
在这里,我试图生成一个约定在一个给定日期三个整月的日期列表。 我想返回一个可以迭代这些日期的迭代器。 这是我第一次尝试:
fn three_months_range(tm: time::Tm) -> std::iter::Iterator<Item=time::Tm> {
let fpm: time::Tm = first_of_previous_month(&tm);
(0..)
.map(|i| fpm + time::Duration::days(i))
.take_while(|&t| t.tm_mon != (tm.tm_mon + 2) % 12)
}
不幸的是,这并不编译,我得到一个错误。
src/main.rs:49:40: 49:75 error: the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator<Item=time::Tm> + 'static` [E0277]
src/main.rs:49 fn three_months_range(tm: time::Tm) -> std::iter::Iterator <Item=time::Tm> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:49:40: 49:75 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:49:40: 49:75 note: `core::iter::Iterator<Item=time::Tm> + 'static` does not have a constant size known at compile-time
src/main.rs:49:40: 49:75 note: the return type of a function must have a statically known size
“函数的返回类型必须具有静态已知大小”。好的,经过一番研究,似乎解决方案是通过Box返回迭代器。我仍然想知道标准库map
,filter
,take_while
...方法如何管理返回迭代器而不是盒子)。
嗯,这里是第二次尝试,成功编译:
fn three_months_range(tm: time::Tm) -> Box<iter::Iterator<Item=time::Tm>> {
let fpm: time::Tm = first_of_previous_month(&tm);
Box::new(
(0..)
.map(move |i| fpm + time::Duration::days(i))
.take_while(move |&t| t.tm_mon != (tm.tm_mon + 2) % 12)
)
}
不幸的是,我不管理使用这个迭代器。 例如,假设我想构建一个包含每个日期的月份日期(1,2,3,...,31,1,2,...,30,1,2,...)的向量。 31):
let days_vec: Vec<u64> =
(*three_months_range(time::now_utc()))
.map(|&t: &time::Tm| t.tm_mday)
.collect();
→
src/main.rs:14:10: 14:42 error: the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator<Item=time::Tm> + 'static` [E0277]
src/main.rs:14 .map(|&t: &time::Tm| t.tm_mday)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:14:10: 14:42 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:14:10: 14:42 note: `core::iter::Iterator<Item=time::Tm> + 'static` does not have a constant size known at compile-time
src/main.rs:15:10: 15:19 error: no method named `collect` found for type `core::iter::Map<core::iter::Iterator<Item=time::Tm> + 'static, [[email protected]/main.rs:14:15: 14:40]>` in the current scope
src/main.rs:15 .collect();
^~~~~~~~~
src/main.rs:15:10: 15:19 note: the method `collect` exists but the following trait bounds were not satisfied: `core::iter::Iterator<Item=time::Tm> : core::marker::Sized`, `[[email protected]/main.rs:14:15: 14:40] : core::ops::FnMut<(time::Tm,)>`, `core::iter::Map<core::iter::Iterator<Item=time::Tm> + 'static, [[email protected]/main.rs:14:15: 14:40]> : core::iter::Iterator`
src/main.rs:14:10: 14:42 error: type mismatch: the type `[[email protected]/main.rs:14:15: 14:40]` implements the trait `for<'r> core::ops::FnMut<(&'r time::Tm,)>`, but the trait `core::ops::FnMut<(time::Tm,)>` is required (expected struct `time::Tm`, found &-ptr) [E0281]
src/main.rs:14 .map(|&t: &time::Tm| t.tm_mday)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:14:10: 14:42 help: run `rustc --explain E0281` to see a detailed explanation
src/main.rs:14:10: 14:42 error: type mismatch: the type `[[email protected]/main.rs:14:15: 14:40]` implements the trait `for<'r> core::ops::FnOnce<(&'r time::Tm,)>`, but the trait `core::ops::FnOnce<(time::Tm,)>` is required (expected struct `time::Tm`, found &-ptr) [E0281]
src/main.rs:14 .map(|&t: &time::Tm| t.tm_mday)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:14:10: 14:42 help: run `rustc --explain E0281` to see a detailed explanation
error: aborting due to 4 previous errors
这是一个很大的错误。
那么我在这里做错了什么?
有没有一种相对简单的方法来转换Rust中的迭代器和/或从函数中返回它们?
注意:你尝试过回' - >()'从功能,让编译器告诉你什么是你创建的迭代器的确切类型,然后使用这个具体键入而不是特质? –
我得到的类型是:'core :: iter :: TakeWhile,[[email protected]/main.rs:64:15:64:53 fpm :_]>,[[email protected]/main.rs:64:66:64:113 tm:_]>' –
关闭会让你进入一个泡菜,他们的类型不能被命名,我看不到明显的方式在这个特殊情况下将功能提升为裸函数不幸的是:( –