如何在struct中存储stdin.lock()保护

时间:2017-11-27 06:12:03

标签: rust lifetime

这里有一个有效的例子。我在main中使用了一个新的stdin句柄。我将它传递给函数parse_something。在此函数中,stdin.lock()返回一个锁定保护,我将其存储到最终返回的结构中。想象结构是某种迭代器。而且我希望这个迭代器只要它是活的就保持stdin锁定。到现在为止还挺好。锁定保护程序与生命周期'a相关联。这是从main的新stdin句柄开始的。

use std::io::BufRead;

struct SomeIterator<B: BufRead> {
    buffer: B,
}

fn parse_something<'a>(stdin: &'a std::io::Stdin) -> SomeIterator<std::io::StdinLock<'a>> {
    let r = SomeIterator {
        buffer: stdin.lock(),
    };
    r
}

fn main() {
    let stdin = std::io::stdin();
    parse_something(&stdin);
}

现在让我们尝试在stdin函数中移动parse_something句柄实例化。

use std::io::BufRead;

struct SomeIterator<B: BufRead> {
    buffer: B,
}

fn parse_something<'a>() -> SomeIterator<std::io::StdinLock<'a>> {
    let stdin = std::io::stdin();
    let r = SomeIterator {
        buffer: stdin.lock(),
    };
    r
}

fn main() {
    parse_something();
}

我收到错误error[E0597]: `stdin` does not live long enough。到现在为止还挺好。 stdin必须和'a一样长。为此,我应该将stdin处理程序存储在SomeIterator

问题是,我必须在.lock()句柄上使用相同生命期stdin的{​​{1}}。我无法弄清楚如何。

这不起作用,因为lockguard引用了'a变量,而不是let stdin中的(最终移动的)stdin属性。

SomeIterator

最终,我全力以赴,并添加了一些随机的垃圾,希望也许我很幸运并且在解决方案上绊倒了。虽然没有运气。在这里,我将struct SomeIterator<B: BufRead> { stdin: std::io::Stdin, buffer: B, } fn parse_something<'a>() -> SomeIterator<std::io::StdinLock<'a>> { let stdin = std::io::stdin(); let guard = stdin.lock(); let r = SomeIterator { stdin: stdin, buffer: guard, }; r } 放在一个方框中。从技术上讲,盒子的内容永远不应该在内存中移动。只有框“指针对象”是。我希望stdin实际上使用Box中内容的生命周期。哪个应该是r.stdin.lock(),因为Box是'a的一部分,SomeIterator本身在'a上是通用的。

可悲的是,r.stdin.lock()在致电r.stdin之前实际借用.lock()时,一切都变得糟透了。这种借用仅适用于函数的范围。 `*r.stdin` does not live long enough点击率很高。

struct SomeIterator<'a, B: BufRead + 'a> {
    stdin: Box<std::io::Stdin>,
    buffer: Option<B>,
    _marker: std::marker::PhantomData<&'a B>,
}

fn parse_something<'a>() -> SomeIterator<'a, std::io::StdinLock<'a>> {
    let mut r = SomeIterator {
        stdin: Box::new(std::io::stdin()),
        buffer: None,
        _marker: std::marker::PhantomData{},
    };
    r.buffer = Some(r.stdin.lock());
    r
}

我怀疑在删除细节之后,我的问题最终变成:安全的Rust是否可以存储对兄弟属性的引用?但我可能是错的。

0 个答案:

没有答案