首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于迭代器来说,锈蚀“没有编译时已知的大小”错误?

对于迭代器来说,锈蚀“没有编译时已知的大小”错误?
EN

Stack Overflow用户
提问于 2021-07-20 11:40:58
回答 1查看 1.3K关注 0票数 1

我正在将Rust的迭代工具1中的笛卡儿产品代码重构为学习Rust的一种方法。笛卡尔积是由Iterator I和IntoIterator J形成的,IntoIterator J被多次转换成迭代器并进行迭代。

到目前为止,我有下面的代码,这是迭代工具源代码中的代码的一个小修改。最大的改变是指定特定类型(i8),而不是使用泛型类型。

代码语言:javascript
运行
复制
struct Product {
    a: dyn Iterator<Item=i8>,
    a_cur: Option<i8>,
    b: dyn IntoIterator<Item=i8, IntoIter=dyn Iterator<Item=i8>>,
    b_iter: dyn Iterator<Item=i8>
}


impl Iterator for Product {

    type Item = (i8, i8);

    fn next(&mut self) -> Option<Self::Item> {
        let elt_b = match self.b_iter.next() {
            None => {
                self.b_iter = self.b.into_iter();
                match self.b_iter.next() {
                    None => return None,
                    Some(x) => {
                        self.a_cur = self.a.next();
                        x
                    }
                }
            }
            Some(x) => x
        };
        match self.a_cur {
            None => None, 
            Some(ref a) => {
                Some((a, elt_b))
            }
        }

    }

}


fn cp(i: impl Iterator<Item=i8>, j: impl IntoIterator<Item=i8>) -> Product {
    
   let p = Product{
       a: i, 
       a_cur: i.next(), 
       b: j, 
       b_iter: j.into_iter()};
   return p

}



fn main() {

    for foo in cp(vec![1,4,7], vec![2,3,9]) {
        println!("{:?}", foo);
    }

}

不幸的是,编译器给出了我无法修复的错误。我尝试了编译器所建议的修复,但是当我做它们时,我得到了更多“在编译时不知道大小”的错误。

我特别困惑,因为Rust的迭代工具库(下面的链接)中的实现具有非常相似的结构,不需要指定生命周期、借用、使用框或dyn关键字。我很想知道我改变了什么,这导致了Rust编译器建议使用借用和/或盒子。

代码语言:javascript
运行
复制
error[E0277]: the size for values of type `(dyn Iterator<Item = i8> + 'static)` cannot be known at compilation time
  --> src/main.rs:15:8
   |
15 |     a: dyn Iterator<Item=i8>,
   |        ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = i8> + 'static)`
   = note: only the last field of a struct may have a dynamically sized type
   = help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
   |
15 |     a: &dyn Iterator<Item=i8>,
   |        ^
help: the `Box` type always has a statically known size and allocates its contents in the heap
   |
15 |     a: Box<dyn Iterator<Item=i8>>,
   |        ^^^^                     ^

error[E0277]: the size for values of type `(dyn IntoIterator<Item = i8, IntoIter = (dyn Iterator<Item = i8> + 'static)> + 'static)` cannot be known at compilation time
  --> src/main.rs:17:8
   |
17 |     b: dyn IntoIterator<Item=i8, IntoIter=dyn Iterator<Item=i8>>,
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `(dyn IntoIterator<Item = i8, IntoIter = (dyn Iterator<Item = i8> + 'static)> + 'static)`
   = note: only the last field of a struct may have a dynamically sized type
   = help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
   |
17 |     b: &dyn IntoIterator<Item=i8, IntoIter=dyn Iterator<Item=i8>>,
   |        ^
help: the `Box` type always has a statically known size and allocates its contents in the heap
   |
17 |     b: Box<dyn IntoIterator<Item=i8, IntoIter=dyn Iterator<Item=i8>>>,
   |        ^^^^                                                         ^

error: aborting due to 2 previous errors

1文档在https://nozaq.github.io/shogi-rs/itertools/trait.Itertools.html#method.cartesian_product,代码在https://github.com/rust-itertools/itertools/blob/master/src/adaptors/mod.rs#L286

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-20 11:59:32

您不仅更改了项目类型,还删除了泛型迭代器。在itertools箱中,有:

代码语言:javascript
运行
复制
pub struct Product<I, J>
    where I: Iterator
{
    a: I,
…

这意味着a是一个迭代器,它的确切类型将由用户指定(但仍在编译时)。

您已经删除了泛型I参数,而是编写了:

代码语言:javascript
运行
复制
pub struct Product
{
    a: dyn Iterator<Item=i8>,
…

如果成功的话,这将意味着a是一个迭代器,其项类型为u8,但其确切类型将在运行时指定。因此,在编译时,编译器无法知道a的确切类型,也不知道它应该分配多少空间来存储aProduct中。

如果您希望您的笛卡尔产品适用于项目为u8的任何迭代器,则需要保留带有额外约束的泛型参数I

代码语言:javascript
运行
复制
pub struct Product<I, J>
    where I: Iterator<Item=u8>
{
    a: I,
…

对于J in impl Iterator,也需要进行类似的更改。

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

https://stackoverflow.com/questions/68454246

复制
相关文章

相似问题

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