迭代收集。 Iterator丢弃后立即删除它

时间:2016-07-26 09:08:10

标签: iterator rust ownership

我将集合转储到磁盘上。在请求时,应检索这些集合(没问题),并且应为其构建 x[!grepl("^[0-9.]+$", x)] <- NA as.numeric(as.character(x)) #[1] 8 80 NA NA NA 106 39 ,以返回对检索到的值的引用。

删除iterator后,我不再需要该集合了。我也想让它掉线。

到目前为止我尝试过:

  1. iterator拥有该集合。这对我来说最有意义,但这是不可能的;我不太清楚为什么。有人说Iterator特征&#39;问题的方法签名是Iterator。 (example

  2. 引用计数:next返回Retriever。我遇到了与拥有迭代器相同的问题。 (example

  3. 让猎人拥有该集合并分发对它的引用。我尝试使用内部可变性(Rc<Vec<usize>>)实现检索器,但我无法将引用返回到RefCell<HashMap>,并且生命周期足够长。

  4. 我看到了两个基本的可能性。

    1. 检索器转移所有权。然后HashMap需要拥有数据。有些东西:

      Iterator
    2. 检索器拥有该集合。但随后出现了两个新问题:

      1. 当迭代器超出范围时,如何删除数据?
      2. 如何告诉借阅检查员我将拥有足够长的收藏品?
      3. use std::slice::Iter;
        
        fn retrieve(id: usize) -> Vec<usize> {
            //Create Data out of the blue (or disk, or memory, or network. I dont care)
            //Move the data out. Transfer ownership
            let data = vec![0, 1, 2, 3];
            data
        }
        
        fn consume_iterator<'a, TIterator: Iterator<Item=&'a usize>>(iterator: TIterator) {
            for i in iterator {
                println!("{}", i);
            }
        }
        
        fn handler<'a>(id: usize) -> Iter<'a, usize> {
            //handle_request now owns the vector.
            //I now want to build an owning iterator..
            //This does of course not compile as vector will be dropped at the end of this method
            retrieve(id).iter()
        }
        
        fn main() {
            consume_iterator(handler(0))
        }
        

        我觉得有点迷失在这里,我忽略了一些显而易见的事情。

2 个答案:

答案 0 :(得分:4)

  

Iterator拥有该系列。 [或通过引用计数共同拥有]

ContainerIterator { 
    data: data,
    iter: data.iter(),
}

不,你cannot have a value and a reference to that value in the same struct

  

让猎人拥有该集合并分发对它的引用。

不,你cannot return references to items owned by the iterator

正如评论者所说,使用IntoIter将项目的所有权转移到迭代器,然后将它们作为迭代值传递出去:

use std::vec::IntoIter;

struct ContainerIterator {
    iter: IntoIter<usize>,
}

impl Iterator for ContainerIterator {
    type Item = usize;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

fn main() {
    let data = vec![0, 1, 2, 3];
    let cont = ContainerIterator { iter: data.into_iter() };

    for x in cont {
        println!("Hi {}", x)
    }
}

如果你必须返回引用...那么你需要在所有引用可能存在的整个时间内保留拥有它们的东西。

  

当迭代器超出范围时,如何删除数据?

不再使用该值:

fn main() {
    {
        let loaded_from_disk = vec![0, 1, 2, 3];
        for i in &loaded_from_disk {
            println!("{}", i)
        }
        // loaded_from_disk goes out of scope and is dropped. Nothing to *do*, per se.
    }
}
  

如何告诉借阅检查员我将拥有足够长的收藏品?

拥有足够长的收藏品。 Rust Illuminati与借用检查器一起使用没有秘密握手。代码只需要被构造成使得借用的东西在借用未偿还时不会变得无效。您无法移动它(更改内存地址)或丢弃它(更改内存地址)。

答案 1 :(得分:1)

我现在终于能够实施一个相对令人满意的解决方案了:

隐藏<dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.2.12</version> <scope>provided</scope> </dependency> s中的迭代器的可变性:

Cell

结构现在需要pub trait OwningIterator<'a> { type Item; fn next(&'a self) -> Option<Self::Item>; } d位置以允许迭代而不会发生突变。 这里的一个例子是一个结构的实现,它既拥有又可以迭代Cell

Arc<Vec<T>>

因为我能够在接口后面隐藏这些迭代器,并让用户只处理&#34;真正的&#34;迭代器我觉得这是可以接受的标准偏差。

感谢所有为最终帮助我找到解决方案的想法做出贡献的人。