首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数参数的特征不匹配

函数参数的特征不匹配
EN

Stack Overflow用户
提问于 2018-01-12 01:18:07
回答 2查看 165关注 0票数 2

我有一段锈蚀代码可以编译,而另一段代码是非常相似的。

起作用的是:

代码语言:javascript
复制
pub fn do_something(_: Box<Iterator<Item = f64>>) {}

fn main() {
    let iter = Box::new(vec![1.0].into_iter());
    do_something(iter);
}

失败的人:

代码语言:javascript
复制
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<..>

我得到以下错误:

代码语言:javascript
复制
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的特点“。但确实如此。有什么问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-12 02:03:17

出于在Box<Box<I>>中讨论的原因,不能强迫Box<Box<Iterator<Item = f64>>>进入这个问题,但可以强制内部Box

代码语言:javascript
复制
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成为强制站点。

代码语言:javascript
复制
    let iter = Box::<Box<Iterator<Item = f64>>>::new(Box::new(vec![1.0].into_iter()));

有效地做了同样的事情。

票数 2
EN

Stack Overflow用户

发布于 2018-01-12 01:29:21

老实说,我根本不是铁锈方面的专家,但我的期望是,你展示的这两个片段都不会编译。这是因为,正如您所指出的,Iterator是一种特性,而不是一种类型,基本上您希望do_something接收实现Iterator的任何类型。也许有一种快捷方式可以使编译器将签名转换为泛型,如果其中一种类型是一种特性,这可能是有时起作用的原因,但我也不太熟悉Rust语言规范。

而不是让do_something采用Iterator (?)使其成为T类型的泛型,其中T是特征绑定的。

代码语言:javascript
复制
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,并且只接受该类型的参数。

代码语言:javascript
复制
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);
}

游乐场

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48218224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档