- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在实现一个小实用程序,编译器告诉我一个变量(TcpStream
)的生命周期不够长,建议我找到一种方法使它的生命周期正好一样长因为它现在还活着。
error[E0597]: `stream` does not live long enough
--> src/main.rs:47:35
|
47 | match handle_request(&mut stream){
| ^^^^^^ borrowed value does not live long enough
...
54 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 43:1...
--> src/main.rs:43:1
|
43 | / fn handle_array(stream: &mut BufReader<TcpStream>) -> Result<Data,Errors>
44 | | {
45 | | let mut array: Vec<Data> = Vec::with_capacity(50);//arbitrary size, picked differently in the complete program
46 | | for _x in 0..50 {
... |
53 | | Ok(Data::Array(array))
54 | | }
| |_^
Rust playground snippet with the exact problem
use std::collections::HashMap;
use std::io::BufReader;
use std::io::Read;
use std::net::TcpStream;
static TOKEN: &[u8; 2] = b"\r\n";
fn main() {}
#[derive(Debug, Clone)]
pub enum Data {
String(Vec<u8>),
Error(Vec<u8>),
Integer(i64),
Binary(Vec<u8>),
Array(Vec<Data>),
Dictionary(HashMap<String, Data>),
}
#[derive(Debug, Clone)]
pub enum Errors<'a> {
CommandError(&'a str),
EndOfConnection,
NotImplemented,
}
pub fn handle_request(stream: &mut BufReader<TcpStream>) -> Result<Data, Errors> {
//TODO handle the empty stream
let mut buff: [u8; 1] = *b"0";
stream.read_exact(&mut buff); //TODO: handle error here
match &buff {
/* part skipped, not relevant */
b"*" => handle_array(stream),
&[_] => Err(Errors::CommandError("Bad request")),
}
}
/*part skipped, not relevant */
fn handle_array(stream: &mut BufReader<TcpStream>) -> Result<Data, Errors> {
let mut array: Vec<Data> = Vec::with_capacity(50); //arbitrary size, picked differently in the complete program
for _x in 0..50 {
match handle_request(&mut stream) {
Ok(x) => array.push(x.clone()),
Err(x) => return Err(x.clone()),
}
}
Ok(Data::Array(array))
}
我真的被这个问题困住了。
看来我不能使用Err的值。如果我更换
match handle_request(&mut stream){
Ok(x) => array.push(x.clone()),
Err(x) => return Err(x.clone()),
}
与
match handle_request(&mut stream){
Ok(x) => array.push(x.clone()),
Err(_) => return Err(Errors::NotImplemented),
}
问题解决了,但不知道为什么。
最佳答案
你的问题可以简化为:
struct Reader;
struct Data;
struct Errors<'a>(&'a str);
fn handle_array(stream: &mut Reader) -> Result<Data, Errors> {
for _ in 0..0 {
handle_request(&mut stream)?;
}
unimplemented!();
}
fn handle_request(_stream: &mut Reader) -> Result<Data, Errors> {
unimplemented!()
}
fn main() {}
error[E0597]: `stream` does not live long enough
--> src/main.rs:7:29
|
7 | handle_request(&mut stream)?;
| ^^^^^^ borrowed value does not live long enough
...
11 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 5:1...
--> src/main.rs:5:1
|
5 | / fn handle_array(stream: &mut Reader) -> Result<Data, Errors> {
6 | | for _ in 0..0 {
7 | | handle_request(&mut stream)?;
8 | | }
9 | |
10 | | unimplemented!();
11 | | }
| |_^
在handle_array
的主体中,stream
的类型是&mut Reader
。但是,当调用 handle_request
时,您对其进行另一个引用,创建一个 &mut &mut Reader
。
向代码添加一些明确的生命周期(出于教育目的,这不会编译),代码看起来有点像这样:
fn handle_array<'stream>(stream: &'stream mut Reader) -> Result<Data, Errors> {
let tmp: &'tmp mut &'stream mut Reader = &mut stream;
if let Err(x) = handle_request(tmp)
handle_request
需要一个 &mut Reader
,因此编译器会插入一些代码来为您对齐这两种类型。编译器必须对其如何执行此转换保持保守,因此它会选择较短的生命周期:
fn handle_array<'stream>(stream: &'stream mut Reader) -> Result<Data, Errors> {
let tmp: &'tmp mut &'stream mut Reader = &mut stream;
let tmp2: &'tmp mut Reader = tmp;
if let Err(x) = handle_request(tmp2)
问题的下一个方面是 lifetime elision 已经启动了这两个函数。它们的扩展形式如下所示:
fn handle_array<'stream>(stream: &'stream mut Reader) -> Result<Data, Errors<'stream>>
fn handle_request<'_stream>(_stream: &_stream mut Reader) -> Result<Data, Errors<'_stream>>
这意味着返回的 Errors
的生命周期与参数的生命周期相关,但在您的情况下,handle_request
的参数具有较短的 'tmp
生命周期,不是 'stream
的生命周期。这说明了为什么会出现编译器错误:您正在尝试返回只能存在于函数内部的Errors
(变量stream
的生命周期> 本身),但您正在尝试返回需要更长寿的引用。
我们可以通过将 stream
传递给 handle_request
来解决这个问题:
handle_request(stream)?;
不幸的是,这只会改变错误:
error[E0499]: cannot borrow `*stream` as mutable more than once at a time
--> src/main.rs:9:40
|
9 | if let Err(x) = handle_request(stream) {
| ^^^^^^ mutable borrow starts here in previous iteration of loop
...
15 | }
| - mutable borrow ends here
这部分更难解释。见:
现在这是 Rust 的一个非常粗糙的边缘,但它越来越接近被修复!但是,现在您有两个主要选择:
这可能行不通,因为您无法从流中读取两次,但在其他情况下它可能会有用:
fn handle_array(stream: &mut Reader) -> Result<Data, Errors> {
let mut array = vec![];
for _ in 0..0 {
if handle_request(stream).is_err() {
return handle_request(stream);
}
if let Ok(r) = handle_request(stream) {
array.push(r);
};
}
unimplemented!();
}
在这种情况下暂时放弃尝试引用。
struct Errors(String);
fn handle_array(stream: &mut Reader) -> Result<Data, Errors> {
let mut array = vec![];
for _ in 0..0 {
array.push(handle_request(stream)?);
}
unimplemented!();
}
我会使用迭代器来提高效率:
fn handle_array(stream: &mut Reader) -> Result<Data, Errors> {
let array = (0..0)
.map(|_| handle_request(stream))
.collect::<Result<Vec<_>, _>>()?;
unimplemented!();
}
使用不稳定 NLL 功能和实验性“Polonius”实现,此代码有效:
struct Errors<'a>(&'a str);
fn handle_array(stream: &mut Reader) -> Result<Data, Errors> {
let mut array = vec![];
for _ in (0..0) {
array.push(handle_request(stream)?);
}
unimplemented!();
}
这还需要一段时间才能普遍可用...
关于rust - "Variable does not live long enough"返回包含引用的结果但它确实存在足够长的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50995241/
我有一个如下所示的数据框: import pandas as pd d = {'decil': ['1. decil','1. decil','2. decil','2. decil','3. dec
我有一些数据想要添加到我的应用中...大约 650 个类别(包括名称 + ID 号),每个类别平均有 85 个项目(每个都有一个名称/ID 号)。 iPhone会支持这么大的plist吗?我想首先在
我目前正在使用 Python 从头开始实现决策树算法。我在实现树的分支时遇到了麻烦。在当前的实现中,我没有使用深度参数。 发生的情况是,要么分支结束得太快(如果我使用标志来防止无限递归),要么如果
我在 Stack 上发现了这个问题 - Measuring the distance between two coordinates in PHP 这个答案在很多方面似乎对我来说都是完美的,但我遇到了
我目前正在清理一个具有 2 个索引和 2.5 亿个事件行以及大约同样多(或更多)的死行的表。我从我的客户端计算机(笔记本电脑)向我的服务器发出命令 VACCUM FULL ANALYZE。在过去的 3
这一切都有点模糊,因为该计划是相当深入的,但坚持我,因为我会尽量解释它。我编写了一个程序,它接受一个.csv文件,并将其转换为MySQL数据库的INSERT INTO语句。例如: ID Numbe
我有一个地址示例:0x003533,它是一个字符串,但要使用它,我需要它是一个 LONG,但我不知道该怎么做:有人有解决方案吗? s 字符串:“0x003533”到长 0x003533 ?? 最佳答案
请保持友善 - 这是我的第一个问题。 =P 基本上作为一个暑期项目,我一直在研究 wikipedia page 上的数据结构列表。并尝试实现它们。上学期我参加了 C++ 类(class),发现它非常有
简单的问题。想知道长 IN 子句是否是一种代码味道?我真的不知道如何证明它。除了我认为的那样,我不知道为什么它会闻起来。 select name, code, capital, pop
我正在尝试基于 C# 中的种子生成一个数字。唯一的问题是种子太大而不能成为 int32。有什么方法可以像种子一样使用 long 吗? 是的,种子必须很长。 最佳答案 这是我移植的 Java.Util.
我一直想知道这个问题有一段时间了。在 CouchDB 中,我们有一些相当的日志 ID……例如: “000ab56cb24aef9b817ac98d55695c6a” 现在,如果我们正在搜索此项目并浏览
列的虚拟列 c和一个给定的值 x等于 1如果 c==x和 0 其他。通常,通过为列创建虚拟对象 c , 一排除一个值 x选择,因为最后一个虚拟列不添加任何信息 w.r.t.已经存在的虚拟列。 这是我如
使用 tarantool,为什么我要记录这些奇怪的消息: 2016-03-24 16:19:58.987 [5803] main/493623/http/XXX.XXX.XXX.XXX:57295 t
我显然是 GitHub 的新手,想确保在开始之前我做的事情是正确的。 我想创建一个新的存储库,它使用来自 2 个现有项目的复刻/克隆。现有项目不是我的。 假设我想使用的 repo 被称为来自开发人员“
我的应用程序名称长度为 17 个字符。当安装在设备上时,它看起来像应用程序...名称。有没有办法在多行上显示应用程序名称?请帮忙。 最佳答案 不,你不能。我认为 iPad 支持 15 个字符来完整显示
我必须编写一个程序来读取文件中的所有单词,并确定每个单词使用了多少次。我的任务是使用多线程来加快运行时间,但是单线程程序的运行速度比多线程程序快。我曾尝试研究此问题的解决方案,但很多解释只会让我更加困
假设我在给定的范围内有一个位置pos,这样: 0 = newRange*newRange : "Case not supported yet"; // Never happens in my code
我试图在 Java 中将 unix 时间四舍五入到该月的第一天,但没有成功。示例: 1314057600 (Tue, 23 Aug 2011 00:00:00 GMT) 至 1312156800
我们的项目有在 CVS 中从现有分支创建新分支的历史。几年后,这导致了每次发布时更改的文件上的这种情况: 新版本:1.145.4.11.2.20.2.6.2.20.2.1.2.11.2.3.2.4.4
我有以下数据框: DAYS7 <- c('Monday','Tuesday','Wednesday','Thursday','Friday', 'Saturday', 'Sunday') DAYS
我是一名优秀的程序员,十分优秀!