- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在写一个库,它应该从实现 BufRead
的东西中读取特征;网络数据流、标准输入等。第一个函数应该从该读取器读取数据单元并返回一个填充的结构,其中大部分填充了 &'a str
。从线路中的帧解析的值。
这是一个最小版本:
mod mymod {
use std::io::prelude::*;
use std::io;
pub fn parse_frame<'a, T>(mut reader: T)
where
T: BufRead,
{
for line in reader.by_ref().lines() {
let line = line.expect("reading header line");
if line.len() == 0 {
// got empty line; done with header
break;
}
// split line
let splitted = line.splitn(2, ':');
let line_parts: Vec<&'a str> = splitted.collect();
println!("{} has value {}", line_parts[0], line_parts[1]);
}
// more reads down here, therefore the reader.by_ref() above
// (otherwise: use of moved value).
}
}
use std::io;
fn main() {
let stdin = io::stdin();
let locked = stdin.lock();
mymod::parse_frame(locked);
}
在尝试不同的解决方案后出现了一个我无法修复的错误:
error: `line` does not live long enough
--> src/main.rs:16:28
|
16 | let splitted = line.splitn(2, ':');
| ^^^^ does not live long enough
...
20 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the body at 8:4...
--> src/main.rs:8:5
|
8 | / {
9 | | for line in reader.by_ref().lines() {
10 | | let line = line.expect("reading header line");
11 | | if line.len() == 0 {
... |
22 | | // (otherwise: use of moved value).
23 | | }
| |_____^
生命周期'a
因为 &str
是在结构和数据管理器结构的实现上定义的需要明确的生命周期。这些代码部分作为最小示例的一部分被删除。
BufReader
有一个 lines()
返回 Result<String, Err>
的方法.我使用 expect
处理错误或 match
从而解压 Result
这样程序现在就有了裸String
.然后将多次执行此操作以填充数据结构。
许多答案都说 unwrap
结果需要绑定(bind)到一个变量,否则它会丢失,因为它是一个临时值。但是我已经保存了解压的 Result
变量中的值 line
我仍然收到错误。
如何修复此错误 - 尝试数小时后仍无法正常工作。
为 &str
做所有这些生命周期声明是否有意义?在数据管理员结构中?这将主要是一个只读数据结构,最多替换整个字段值。 String
也可以使用,但发现文章说 String
性能低于 &str
- 并且此帧解析器函数将被调用多次并且对性能至关重要。
Stack Overflow 上存在类似的问题,但没有一个能完全回答这里的情况。
为了完整性和更好的理解,以下是完整源代码的摘录,说明为什么会出现生命周期问题:
数据结构声明:
// tuple
pub struct Header<'a>(pub &'a str, pub &'a str);
pub struct Frame<'a> {
pub frameType: String,
pub bodyType: &'a str,
pub port: &'a str,
pub headers: Vec<Header<'a>>,
pub body: Vec<u8>,
}
impl<'a> Frame<'a> {
pub fn marshal(&'a self) {
//TODO
println!("marshal!");
}
}
完整的函数定义:
pub fn parse_frame<'a, T>(mut reader: T) -> Result<Frame<'a>, io::Error> where T: BufRead {
最佳答案
你的问题可以简化为:
fn foo<'a>() {
let thing = String::from("a b");
let parts: Vec<&'a str> = thing.split(" ").collect();
}
您创建一个 String
在你的函数中,然后声明对该字符串的引用保证在整个生命周期内存在'a
.可惜一生'a
不在你的控制之下——函数的调用者可以选择生命周期。这就是通用参数的工作原理!
如果函数的调用者指定了 'static
会发生什么生命周期?您的代码在运行时分配一个值,怎么可能保证该值甚至比 main
的生命周期更长?功能?不可能,这就是编译器报错的原因。
一旦你获得了更多的经验,函数签名 fn foo<'a>()
会像红色警报一样跳到您面前 — 有一个未使用 的通用参数。这很可能意味着坏消息。
return a populated struct filled mostly with
&'a str
你不可能用你当前的代码组织来做到这一点。引用必须指向某物。您没有为指向的值提供生存的任何地方。你不能 return an allocated String
as a string slice .
在你跳到它之前,没有你cannot store a value and a reference to that value in the same struct .
相反,您需要拆分创建 String
的代码以及解析 &str
的那个并返回更多 &str
引用。这就是所有现有的零拷贝解析器的工作方式。您可以查看这些以获取灵感。
String
has lower performance than&str
不,它真的没有。创造大量无关的String
当然,s 是一个坏主意,就像在任何语言中分配太多都是一个坏主意一样。
关于rust - 无法将字符串拆分为具有显式生命周期的字符串切片,因为该字符串的生命周期不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44641830/
我正在开发一个使用多个 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
我是一名优秀的程序员,十分优秀!