Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何收集到数组中?_Rust - Fatal编程技术网

Rust 如何收集到数组中?

Rust 如何收集到数组中?,rust,Rust,我想对枚举数组调用.map(): enum Foo { Value(i32), Nothing, } fn main() { let bar = [1, 2, 3]; let foos = bar.iter().map(|x| Foo::Value(*x)).collect::<[Foo; 3]>(); } enum Foo{ 值(i32), 没有什么, } fn main(){ 设bar=[1,2,3]; 设foos=bar.iter().map

我想对枚举数组调用
.map()

enum Foo {
    Value(i32),
    Nothing,
}

fn main() {
    let bar = [1, 2, 3];
    let foos = bar.iter().map(|x| Foo::Value(*x)).collect::<[Foo; 3]>();
}
enum Foo{
值(i32),
没有什么,
}
fn main(){
设bar=[1,2,3];
设foos=bar.iter().map(|x | Foo::Value(*x)).collect::();
}
但编译器抱怨:

error[E0277]:不满足特性绑定“[Foo;3]:std::iter::fromtiterator”
-->src/main.rs:8:51
|
8 |让foos=bar.iter().map(|x | Foo::Value(*x)).collect::();
|^^^^无法通过迭代器在`Foo;类型的元素上生成`Foo;3]`类型的集合`
|
=help:trait`std::iter::fromtiterator`未为`[Foo;3]实现`

我如何做到这一点?

这是不可能的,因为数组没有实现任何特征。您只能收集到实现<代码>FromIterator特性的类型中(请参见本部分底部的列表)


这是一种语言限制,因为目前不可能对数组的长度进行泛型,并且长度是其类型的一部分。但是,即使有可能,也不太可能在数组上实现来自迭代器的
,因为如果生成的项数与数组的长度不完全一致,它将不得不惊慌失措。

在这种情况下,您可以使用
Vec

#[派生(调试)]
enum Foo{
值(i32),
没有什么,
}
fn main(){
设bar=[1,2,3];
设foos=bar.iter().map(|&x | Foo::Value(x)).collect::();
println!(“{:?}”,foos);
}

问题实际上在
收集中,而不是在
地图中

为了能够将迭代的结果收集到一个容器中,这个容器应该实现
FromIterator

[T;n]
没有实现来自迭代器的
,因为它通常无法实现:要生成
[T;n]
您需要准确地提供
n
元素,但是在使用
来自迭代器的
时,您无法保证将输入到您的类型中的元素数量

还有一个困难是,如果没有补充数据,您将不知道现在应该输入数组的哪个索引(以及它是空的还是满的),等等。。。这可以通过在
map
之后使用
enumerate
来解决(基本上是输入索引),但是如果提供的元素不够或太多,您仍然需要决定该怎么做

因此,不仅目前无法在固定大小的数组上实现
FromIterator
;但即使在未来,这似乎也是一个遥远的目标


那么,现在该怎么办?有几种可能性:

  • 在调用站点内联转换:
    [值(1)、值(2)、值(3)]
    ,可能需要宏的帮助
  • 收集到不同的(可增长的)容器中,例如
    Vec

    • 我自己也遇到了这个问题-这里有一个解决方法

      您不能使用迭代器中的
      ,但您可以迭代固定大小对象的内容,或者,如果事情更复杂,可以使用索引来分割任何可以访问的内容。无论哪种方式,突变都是可行的

      例如,我遇到的问题是类型为
      [[usize;2];4]
      的数组:

      fn main() {
          // Some input that could come from another function and thus not be mutable
          let pairs: [[usize; 2]; 4] = [[0, 0], [0, 1], [1, 1], [1, 0]];
      
          // Copy mutable
          let mut foo_pairs = pairs.clone();
      
          for pair in foo_pairs.iter_mut() {
              // Do some operation or other on the fixed-size contents of each
              pair[0] += 1;
              pair[1] -= 1;
          }
          // Go forth and foo the foo_pairs
      }
      
      如果这发生在一个小函数中,在我的书中是可以的。无论哪种方式,最终都会得到一个与同一类型相同的转换值,因此,首先复制整个内容,然后进行变异,这与在闭包中引用一个值并返回它的某个函数的工作量大致相同


      请注意,只有当您计划计算相同类型的内容时,这才有效,包括大小/长度。但你使用的锈菌阵列暗示了这一点。(具体地说,您可以
      Value()
      您的
      Foo
      s或
      Nothing
      任意选择它们,并且仍然在数组的类型参数范围内。)

      虽然由于其他答案所述的原因,您无法直接收集到数组中,但这并不意味着您无法收集到由数组支持的数据结构中,例如:

      使用arrayvec::arrayvec;//0.7.0
      使用std::数组;
      enum Foo{
      值(i32),
      没有什么,
      }
      fn main(){
      设bar=[1,2,3];
      让foos:ArrayVec=array::IntoIter::new(bar).map(Foo::Value.collect();
      让_数组=foos
      .into_inner()
      .unwrap_或_else(| | panic!(“数组未完全填充”);
      }
      
      将数组从
      ArrayVec
      中拉出将返回
      结果
      ,以处理没有足够的项填充数组的情况;其他答案中讨论的案例。

      .collect()
      构建了可以具有任意长度的数据结构,因为迭代器的项目号通常不受限制。(谢普马斯特的回答已经提供了很多细节)

      从映射链获取数据而不分配
      Vec
      或类似内容的一种可能性是将数组的可变引用引入链中。在您的示例中,看起来是这样的:

      #[derive(Debug, Clone, Copy)]
      enum Foo {
          Value(i32),
          Nothing,
      }
      
      fn main() {
          let bar = [1, 2, 3];
          let mut foos = [Foo::Nothing; 3];
          bar.iter().map(|x| Foo::Value(*x))
              .zip(foos.iter_mut()).for_each(|(b, df)| *df = b);
      }
      

      .zip()
      使迭代以锁步方式在
      bar
      foos
      上运行——如果
      foos
      分配不足,则较高的
      bar
      将根本不会被映射,如果分配过度,它将保留其原始初始化值。(因此,
      [Nothing;3]
      初始化也需要克隆和复制)。

      您实际上可以定义一个
      迭代器来完成此操作

      使用std::convert::AsMut;
      使用std::default::default;
      trait castex:大小+迭代器{
      fn铸造(多自)->U{
      释放mut:U=U::default();
      设arr:&mut[T]=out.as_mut();
      对于0..arr.len()中的i{
      匹配self.next(){
      None=>panic!(“数组未填充”),
      一些(v)=>arr[
      
      use arrayvec::ArrayVec; // 0.7.0
      use std::array;
      
      enum Foo {
          Value(i32),
          Nothing,
      }
      
      fn main() {
          let bar = [1, 2, 3];
          let foos: ArrayVec<_, 3> = array::IntoIter::new(bar).map(Foo::Value).collect();
          let the_array = foos
              .into_inner()
              .unwrap_or_else(|_| panic!("Array was not completely filled"));
      }
      
      #[derive(Debug, Clone, Copy)]
      enum Foo {
          Value(i32),
          Nothing,
      }
      
      fn main() {
          let bar = [1, 2, 3];
          let mut foos = [Foo::Nothing; 3];
          bar.iter().map(|x| Foo::Value(*x))
              .zip(foos.iter_mut()).for_each(|(b, df)| *df = b);
      }