Rust 锈蚀:如何修复借来的价值活得不够长
我有一个简单的客户机/服务器应用程序。我在服务器端收到来自客户端的消息,但我想将该响应发送到从服务器到其他文件的通道,并且我收到错误“借用值的寿命不够长” 我在stack overflow中搜索了前面类似的问题,但没有对lifetime有足够的了解。关于这个主题是否有好的文档或简单的例子 现在,如果有人能帮我修复这段代码(可能是编辑需要修复的代码部分),那将是很有帮助的 提前谢谢 服务器端: 我犯了一个错误Rust 锈蚀:如何修复借来的价值活得不够长,rust,Rust,我有一个简单的客户机/服务器应用程序。我在服务器端收到来自客户端的消息,但我想将该响应发送到从服务器到其他文件的通道,并且我收到错误“借用值的寿命不够长” 我在stack overflow中搜索了前面类似的问题,但没有对lifetime有足够的了解。关于这个主题是否有好的文档或简单的例子 现在,如果有人能帮我修复这段代码(可能是编辑需要修复的代码部分),那将是很有帮助的 提前谢谢 服务器端: 我犯了一个错误 error[E0597]: `buf` does not live long enoug
error[E0597]: `buf` does not live long enough
--> src/unix_datagram_server.rs:38:42
|
38 | let received_message = from_utf8(buf.as_slice()).expect("utf-8 convert failed");
| ^^^ borrowed value does not live long enough
...
41 | }
| -
| |
| `buf` dropped here while still borrowed
| borrow might be used here, when `tx` is dropped and runs the `Drop` code for type `std::sync::mpsc::Sender`
|
= note: values in a scope are dropped in the opposite order they are defined
error: aborting due to previous error; 8 warnings emitted
编译器消息中有一个提示,作用域中的值按定义的相反顺序删除,在示例中,
buf
是在tx
之后定义的,这意味着它将在tx
之前删除。由于对buf
的引用(以received_message
的形式)被传递到tx.send()
,因此buf
应该比该tx的寿命更长,因此切换定义顺序将修复此特定错误(即切换第19行和第20行)
现在,如果有人能帮我修复这段代码(可能是编辑需要修复的代码部分),那将是很有帮助的
嗯,这个信息似乎相当清楚send
完全按照它所说的做,它通过通道发送参数。这意味着数据必须存在足够长的时间,并且“永远”保持有效(它需要在通道中处于活动状态且有效,以及在接收器从中获取数据时)
这里的情况并非如此。rustc无法理解该函数永远不会返回,并且它可能会死机,这将导致相同的结果:该函数将终止,从而使buf
无效。由于received_message
借用了buf
,这意味着received_message
在函数终止后无法生效。但在这一点上,消息仍将在通道中等待读取(或由接收者进行检索,谁知道是什么)
因此,您的施工是不允许的
第二个问题是在每个循环上覆盖缓冲区数据,这与中断上一次迭代中发送的消息的效果相同,因此也是不正确的。尽管Rust也不允许您这样做:如果您解决了第一个错误,它会告诉您存在未完成的共享借用(通过通道发送的消息),因此您无法在下面的迭代中修改备份缓冲区
解决方案非常简单:让每个迭代创建一个拥有的字符串(复制当前迭代的消息),并通过通道发送:
tx.clone().send(received_message.to_string());
此外,这些都是风格/效率低下的评论,但:
上的tx
是完全冗余的。拥有一个clone()
发送方的意义在于能够从多个线程发送(因此通道名称中有mp,这是针对多个生产者的)。这里你有一个单一的线程,原来的发送者工作良好Clone
和.as_slice()
除非必要,否则很少使用,它们不在这里:数组引用强制使用切片,因此您可以只使用.as_mut_slice()
和&mut buf
。为什么要在已经是路径的东西上调用&buf
?它没什么用,但也没用Path::new
- 您的代码段缺少多个导入,因此甚至无法按原样编译,这相当令人恼火
- 从更为单向的角度来看,错误通常打印在stderr上。在Rust中,
会为您执行此操作(否则以与eprintln
相同的方式执行)。我不明白标记一个词汇嵌套的println
静态
发布
的目的。由于
位于函数内部,因此函数的同级甚至不可见,更不用说外部调用者了。因此,我最终会得出以下结论:静态
使用std::os::unix::net::UnixDatagram; 使用std::path::path; 使用std::sync::mpsc; 使用std::str::from_utf8; fn取消链接_套接字(路径:impl AsRef){ 设path=path.as_ref(); 如果path.exists()存在{ 如果让Err(e)=std::fs::remove_文件(路径){ eprintln!(“无法删除文件:{:?}”,e); } } } 静态文件路径:&'static str=“/tmp/datagram.sock”; 发布fn tcp_数据报_服务器(){ 取消链接\u套接字(文件\u路径); 让套接字=匹配UnixDatagram::bind(文件路径){ 正常(插座)=>插座, 错误(e)=>{ eprintln!(“无法绑定:{:?}”,e); 返回; } }; let(tx,u)=mpsc::channel(); 设mut buf=vec![0;1024]; println!(“正在等待客户端连接…”); 环路{ let received_bytes=socket.recv(&mut buf).expect(“recv函数失败”); println!(“接收的{:?}”,接收的字节); 让我们接收来自utf8(&buf)的消息。预期(“utf-8转换失败”); tx.send(接收到的_message.to_string()); } }
error[E0597]: `buf` does not live long enough
--> src/unix_datagram_server.rs:38:42
|
38 | let received_message = from_utf8(buf.as_slice()).expect("utf-8 convert failed");
| ^^^ borrowed value does not live long enough
...
41 | }
| -
| |
| `buf` dropped here while still borrowed
| borrow might be used here, when `tx` is dropped and runs the `Drop` code for type `std::sync::mpsc::Sender`
|
= note: values in a scope are dropped in the opposite order they are defined
error: aborting due to previous error; 8 warnings emitted
tx.clone().send(received_message.to_string());