- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在用 Rust 编写词法分析器时遇到问题,其中某些函数开始提示简单的片段,否则这些片段看起来无害。这开始变得令人烦恼,因为错误消息无法帮助我查明问题的原因,所以这是我第二次在同一周内联系同一程序(上一个问题 here)。
我读过这本书,我已经了解了我能从中了解的一切。我还观看/阅读了许多其他讨论生命周期(显式和隐式)的文章和视频,并且在大多数情况下,借用和移动背后的概念非常有意义,但以下情况除外:
我的词法分析器有一个 next
函数,它的目的是向前看下一个字符并返回它。
struct Lexer<'a> {
src: str::Chars<'a>,
buf: String,
// ... not important
}
impl<'a> Lexer<'a> {
// ... not relevant
// originally this -> Option<&char> which caused it's own slew of problems
// that I thought dereferencing the character would solve.
fn next(&self) -> Option<char> {
let res = self.src.peekable().peek();
// convert Option<&char> to Option<char>
match res {
Some(ref c) => Some(*c.clone()),
None => None
}
}
// ... not relevant
}
我在执行此操作时遇到的错误是:
error: borrowed value does not live long enough
let res = self.src.peekable().peek();
^~~~~~~~~~~~~~~~~~~
我从这个错误中了解到,peekable()
的值生命周期不够长,这对我来说很有意义。我只是在该行中引用 return 并调用另一个函数,我想它会使用迭代器返回指向下一个位置的字符的指针。我天真的解决方案是:
let mut peeker = self.src.peekable();
let res = peeker.peek();
如果我实现这个解决方案,我会看到一个不同的错误,这对我来说也没有意义:
error: cannot move out of borrowed content
let mut peeker = self.src.peekable();
^~~~
我不太确定是什么将 self
从借用的上下文中移出(我知道它是从 &self
中借用的,但不确定是什么将它从借用的上下文中移出.
编辑
我提出了一个问题,其中的细节非常不准确。帖子中包含这些详细信息的部分已根据实际情况进行了更新 - 我将遇到类似错误的两种不同情况混为一谈(至少与我相似)。
最佳答案
让我们从第二个错误开始。
如评论中所述,Iterator::peekable
是一个迭代器适配器,消耗 它将使其可窥视的迭代器。一个小复制品:
let values = [1,2,3];
let mut iterator = values.iter();
iterator.peekable(); // Consumes `iterator`
iterator.next(); // Not available anymore!
您可以使用 Iterator::by_ref
来获取一个引用,该引用本身可以被使用。请注意,底层迭代器仍将被推进!
let values = [1,2,3];
let mut iterator = values.iter();
iterator.by_ref().peekable();
iterator.next();
在您的情况下,您正在尝试使用借用结构的值(通过 &self
),它具有特定错误 cannot move out of borrowed content
。
让我们看看您的原始错误:
let values = [1,2,3];
let next = values.iter().peekable().peek();
这里的问题是 peek
返回一个 reference。这是有道理的,因为我们不知道我们正在迭代的项目是否可以Copy
。但是,该引用必须有一个地方可以住。这个地方就是 Peekable
迭代器本身! Peekable
分配足够的空间来存储“下一个”元素。当您调用 peek
时,它会推进底层迭代器,存储值,然后返回引用。查看 peek
的函数签名以查看在代码中捕获的内容:
fn peek(&mut self) -> Option<&I::Item>
您可以重新添加明确的生命周期:
fn peek<'a>(&'a mut self) -> Option<&'a I::Item>
在单行版本中,您创建然后销毁 Peekable
,因此值无处可存,因此引用在同一语句中消失。
关于rust - 与(表面上)看起来非常安全的短暂生命周期值混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29805958/
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!