Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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
Iterator 如何使用生命周期嵌套可变访问?_Iterator_Streaming_Rust_Lifetime_Borrow Checker - Fatal编程技术网

Iterator 如何使用生命周期嵌套可变访问?

Iterator 如何使用生命周期嵌套可变访问?,iterator,streaming,rust,lifetime,borrow-checker,Iterator,Streaming,Rust,Lifetime,Borrow Checker,我正在用Rust编写解析流的代码,trait-Stream。这些流可以由其他流组成。traitStreamIterator允许访问子流。这是在解析tar文件、zip文件和其他包含文件的文件时发生的 在编写这段代码时,我一直在与借阅检查器抗争,但没有成功 下面的代码是一个简化的示例。在main中,文件作为流打开。该流被传递到analyze函数,该函数尝试以TarStreamIterator的形式打开该流,以迭代tar中的流。还分析了每个嵌入流 我想我可能需要在StreamIterator特性中引入

我正在用Rust编写解析流的代码,
trait-Stream
。这些流可以由其他流组成。trait
StreamIterator
允许访问子流。这是在解析tar文件、zip文件和其他包含文件的文件时发生的

在编写这段代码时,我一直在与借阅检查器抗争,但没有成功

下面的代码是一个简化的示例。在
main
中,文件作为流打开。该流被传递到
analyze
函数,该函数尝试以
TarStreamIterator
的形式打开该流,以迭代tar中的流。还分析了每个嵌入流

我想我可能需要在
StreamIterator
特性中引入第二个生命周期

use std::io;
trait Stream<T> {
    fn read(&mut self) -> io::Result<&[T]>;
}
trait StreamIterator<'a,T,S: Stream<T>> {
    fn next(&'a mut self) -> Option<io::Result<S>>;
}
struct FileStream {
}
impl<T> Stream<T> for FileStream {
    fn read(&mut self) -> io::Result<&[T]> {
        Err(io::Error::new(io::ErrorKind::UnexpectedEof, ""))
    }
}
struct TarStream<'a> {
    stream: &'a mut Stream<u8>
}
impl<'a> Stream<u8> for TarStream<'a> {
    fn read(&mut self) -> io::Result<&[u8]> {
        self.stream.read()
    }
}
struct TarStreamIterator<'a> {
    stream: &'a mut Stream<u8>
}
impl<'a> StreamIterator<'a,u8,TarStream<'a>> for TarStreamIterator<'a> {
    fn next(&'a mut self) -> Option<io::Result<TarStream>> {
        // todo: read tar header
        Some(Ok(TarStream{stream: self.stream}))
    }
}
fn analyzeAsTar(s: &mut Stream<u8>) -> bool {
    let mut tar = TarStreamIterator{stream: s};
    while let Some(Ok(mut substream)) = tar.next() {
        analyze(&mut substream);
    }
    true
}
fn analyze(s: &mut Stream<u8>) -> bool {
    analyzeAsTar(s)
}
fn main() {
    let mut fs = FileStream{};
    analyze(&mut fs);
}
使用std::io;
特征流{
fn read(&mut self)->io::Result;
}
特征流迭代器选项;
}
结构文件流{
}
文件流的impl流{
fn读取(&mut self)->io::结果{
Err(io::Error::new(io::ErrorKind::UnexpectedEof,“”)
}
}
结构塔斯里姆{
fn读取(&mut self)->io::结果{
self.stream.read()
}
}
结构流迭代器{
fn下一步(&'a mut self)->选项{
//todo:读取tar标题
一些(Ok(TarStream{stream:self.stream}))
}
}
fn分析星(s:&mut流)->bool{
设mut tar=TarStreamIterator{stream:s};
而让Some(Ok(mut substream))=tar.next(){
分析(&mut子流);
}
真的
}
fn分析(s:&mut流)->bool{
分析星
}
fn main(){
让mut fs=FileStream{};
分析(&mut-fs);
}
这会产生以下错误:

<anon>:38:41: 38:44 error: cannot borrow `tar` as mutable more than once at a time [E0499]
<anon>:38     while let Some(Ok(mut substream)) = tar.next() {
                                                  ^~~
<anon>:38:41: 38:44 help: see the detailed explanation for E0499
<anon>:38:41: 38:44 note: previous borrow of `tar` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `tar` until the borrow ends
<anon>:38     while let Some(Ok(mut substream)) = tar.next() {
                                                  ^~~
<anon>:42:2: 42:2 note: previous borrow ends here
<anon>:36 fn analyzeAsTar(s: &mut Stream<u8>) -> bool {
          ...
<anon>:42 }
:38:41:38:44错误:不能一次多次借用'tar'作为可变项[E0499]
:38而让一些(Ok(mut substream))=tar.next(){
^~~
:38:41:38:44帮助:请参阅E0499的详细说明
:38:41:38:44注:“tar”的上一次借用发生在此处;可变借用阻止后续移动、借用或修改“tar”,直到借用结束
:38而让一些(Ok(mut substream))=tar.next(){
^~~
:42:2:42:2注:以前的借用到此结束
:36 fn分析星(s:&mut流)->bool{
...
:42 }

有一个解决方法。可以将trait与
next()
函数一起使用,而不是将trait与
iterate
函数一起使用。在下面的示例中,
TarStreamIterator
有一个函数
iterate
可以接受闭包。(或者,
iterator
可以分别调用

该实现仍然具有
next
功能,但借用检查器接受此表单

这个简短的示例实际上对流没有任何作用

use std::io;
// generic version of std::io::Read
trait Stream<T> {
    fn read(&mut self) -> io::Result<&[T]>;
}
trait StreamIterator<T> {
    // call `f` on each of the streams in the iterator
    fn iterate<F>(&mut self, mut f: F) where F: FnMut(&mut Stream<T>);
}
struct FileStream {
}
impl<T> Stream<T> for FileStream {
    fn read(&mut self) -> io::Result<&[T]> {
        Err(io::Error::new(io::ErrorKind::UnexpectedEof, ""))
    }
}
struct TarStream<'a> {
    stream: &'a mut Stream<u8>
}
impl<'a> Stream<u8> for TarStream<'a> {
    fn read(&mut self) -> io::Result<&[u8]> {
        self.stream.read()
    }
}
struct TarStreamIterator<'a> {
    stream: &'a mut Stream<u8>
}
impl<'a> TarStreamIterator<'a> {
    // pass the next embedded stream or None if there are no more
    fn next(&mut self) -> Option<TarStream> {
        Some(TarStream{stream: self.stream})
    }
}
impl<'a> StreamIterator<u8> for TarStreamIterator<'a> {
    fn iterate<F>(&mut self, mut f: F) where F: FnMut(&mut Stream<u8>) {
        while let Some(mut substream) = self.next() {
            f(&mut substream);
        }
    }
}
fn analyze_as_tar(stream: &mut Stream<u8>) {
    TarStreamIterator{stream: stream}.iterate(|substream| {
        analyze(substream);
    });
}
fn analyze(s: &mut Stream<u8>) {
    analyze_as_tar(s)
}
fn main() {
    let mut fs = FileStream{};
    analyze(&mut fs);
}
使用std::io;
//std::io::Read的通用版本
特征流{
fn read(&mut self)->io::Result;
}
特征流迭代器{
//对迭代器中的每个流调用'f'
fn迭代(&mut self,mut f:f),其中f:FnMut(&mut Stream);
}
结构文件流{
}
文件流的impl流{
fn读取(&mut self)->io::结果{
Err(io::Error::new(io::ErrorKind::UnexpectedEof,“”)
}
}
结构塔斯里姆{
fn读取(&mut self)->io::结果{
self.stream.read()
}
}
结构流迭代器{
//传递下一个嵌入流,如果没有,则不传递
fn下一步(&mut self)->选项{
一些(TarStream{stream:self.stream})
}
}
恳求{
fn迭代(&mut self,mut f:f),其中f:FnMut(&mut Stream){
而让Some(mut substream)=self.next(){
f(&mut子流);
}
}
}
fn分析作为tar(流:&mut流){
TarStreamIterator{stream:stream}.iterate(| substream |{
分析(子流);
});
}
fn分析(s:&mut流){
作为焦油分析
}
fn main(){
让mut fs=FileStream{};
分析(&mut-fs);
}

有趣的是,您正在尝试创建所谓的流式迭代器,该迭代器作为合同的一部分返回对自身的引用。有项目、Reddit线程,甚至关于主题。