我有一段锈蚀代码可以编译,而另一段代码是非常相似的。
起作用的是:
pub fn do_something(_: Box<Iterator<Item = f64>>) {}
fn main() {
let iter = Box::new(vec![1.0].into_iter());
do_something(iter);
}失败的人:
pub fn do_something(_: Box<Box<Iterator<Item = f64>>>) {}
fn main() {
let iter = Box::new(Box::new(vec![1.0].into_iter()));
do_something(iter);
}区别在于我有一个Box<Box<..>>而不是一个Box<..>
我得到以下错误:
error[E0308]: mismatched types
--> src/main.rs:5:18
|
5 | do_something(iter);
| ^^^^ expected trait std::iter::Iterator, found struct `std::vec::IntoIter`
|
= note: expected type `std::boxed::Box<std::boxed::Box<std::iter::Iterator<Item=f64> + 'static>>`
found type `std::boxed::Box<std::boxed::Box<std::vec::IntoIter<{float}>>>`我把这个错误解释为"IntoIter没有Iterator的特点“。但确实如此。有什么问题吗?
发布于 2018-01-12 02:03:17
出于在Box<Box<I>>中讨论的原因,不能强迫Box<Box<Iterator<Item = f64>>>进入这个问题,但可以强制内部Box
pub fn do_something(_: Box<Box<Iterator<Item = f64>>>) {}
fn main() {
let iter = Box::new(Box::new(vec![1.0].into_iter()) as Box<Iterator<Item = f64>>);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
do_something(iter);
}游乐场。
这是因为强制转换是一个胁迫站点。通过编写as Box<Iterator<Item = f64>>,您可以向编译器暗示,它应该尝试将表达式设置为该类型,而不是推断Box<IntoIter<f64>>,因为一旦它封装在“外部”Box中,您就不能再修改它了。
或者(但不太清楚),您可以通过显式参数化Box::new(...)使Box成为强制站点。
let iter = Box::<Box<Iterator<Item = f64>>>::new(Box::new(vec![1.0].into_iter()));有效地做了同样的事情。
发布于 2018-01-12 01:29:21
老实说,我根本不是铁锈方面的专家,但我的期望是,你展示的这两个片段都不会编译。这是因为,正如您所指出的,Iterator是一种特性,而不是一种类型,基本上您希望do_something接收实现Iterator的任何类型。也许有一种快捷方式可以使编译器将签名转换为泛型,如果其中一种类型是一种特性,这可能是有时起作用的原因,但我也不太熟悉Rust语言规范。
而不是让do_something采用Iterator (?)使其成为T类型的泛型,其中T是特征绑定的。
pub fn do_something<T>(_: Box<Box<T>>)
where T: Iterator<Item = f64> + Send {}
fn main() {
let iter = Box::new(Box::new(vec![1.0].into_iter()));
do_something(iter);
}或者,将do_something完全约束为std::vec::IntoIter,并且只接受该类型的参数。
pub fn do_something(_: Box<Box<std::vec::IntoIter<f64>>>) {}
fn main() {
let iter = Box::new(Box::new(vec![1.0].into_iter()));
do_something(iter);
}https://stackoverflow.com/questions/48218224
复制相似问题