Rust 锈蚀:如何修复借来的价值活得不够长

Rust 锈蚀:如何修复借来的价值活得不够长,rust,Rust,我有一个简单的客户机/服务器应用程序。我在服务器端收到来自客户端的消息,但我想将该响应发送到从服务器到其他文件的通道,并且我收到错误“借用值的寿命不够长” 我在stack overflow中搜索了前面类似的问题,但没有对lifetime有足够的了解。关于这个主题是否有好的文档或简单的例子 现在,如果有人能帮我修复这段代码(可能是编辑需要修复的代码部分),那将是很有帮助的 提前谢谢 服务器端: 我犯了一个错误 error[E0597]: `buf` does not live long enoug

我有一个简单的客户机/服务器应用程序。我在服务器端收到来自客户端的消息,但我想将该响应发送到从服务器到其他文件的通道,并且我收到错误“借用值的寿命不够长”

我在stack overflow中搜索了前面类似的问题,但没有对lifetime有足够的了解。关于这个主题是否有好的文档或简单的例子

现在,如果有人能帮我修复这段代码(可能是编辑需要修复的代码部分),那将是很有帮助的

提前谢谢

服务器端: 我犯了一个错误

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()
    是完全冗余的。拥有一个
    Clone
    发送方的意义在于能够从多个线程发送(因此通道名称中有mp,这是针对多个生产者的)。这里你有一个单一的线程,原来的发送者工作良好

  • .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());