英文:
Why passing a Bytes to a function leads to lifetime error, even though it's guaranteed to complete before drop? and how to fix?
问题
Explanation:
The error you're encountering is related to the lifetime of the text_owned variable in your code. The text_owned variable is created by cloning the text field from the msg.content in the if let block. However, when you try to create a Bytes instance from text_owned.as_bytes(), the compiler is indicating that text_owned does not live long enough for this operation.
The issue arises because the Bytes::from function expects its argument to have a 'static lifetime, which means it should live for the entire duration of the program. In your case, text_owned is a temporary value that only lives within the scope of the if let block, and it goes out of scope when the block ends.
How to Fix:
To fix this issue, you need to ensure that the data you're using to create the Bytes instance lives for a 'static lifetime. One way to do this is by cloning the text into a Vec<u8> and then creating the Bytes instance from the Vec. Here's how you can modify your code:
if let Content::Text(ref text) = msg.content {
let text_vec = text.clone().into_bytes(); // Convert String to Vec<u8>
let text_byte = Bytes::from(text_vec);
let mut online_users = online_users.lock().await;
online_users.send_to_user(target_user, text_byte).await;
}
In this code, text_vec is a Vec<u8> created from the cloned text, and it can be used to create the Bytes instance without lifetime issues.
This modification ensures that the data used to create text_byte lives long enough for the Bytes instance.
英文:
My current code using bytes crate:
pub async fn send_msg(online_users: Arc<Mutex<OnlineUsers>>, msg: &Message, from: &str) -> io::Result<()> {
let target_user = msg.args.get(0).ok_or(io::Error::from(io::ErrorKind::InvalidInput))?;
if let Content::Text(ref text) = msg.content {
let text_owned = text.clone();
let text_byte = Bytes::from(text_owned.as_bytes());
let mut online_users = online_users.lock().await;
online_users.send_to_user(target_user, text_byte).await;
}
Ok(())
}
The error occurs at the call of send_to_user(), the definition of it is:
pub async fn send_to_user(&mut self, name: &str, content: Bytes) -> io::Result<()> {
let target_user = self
.list
.get_mut(name)
.ok_or(io::Error::new(io::ErrorKind::NotConnected, name.clone()))?;
target_user.send(content).await?;
Ok(())
}
Error message below:
error[E0597]: `text_owned` does not live long enough
--> server/src/handler.rs:28:37
|
28 | let text_byte = Bytes::from(text_owned.as_bytes());
| ------------^^^^^^^^^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `text_owned` is borrowed for `'static`
...
31 | }
| - `text_owned` dropped here while still borrowed
I do not understand why it does not live long enough. Since I called .await on an send_to_user(), it must complete before send_msg() reaches its end and drop all variables.
I want:
- explanation why this happens.
- how am I able to fix this?
答案1
得分: 1
Bytes::from 适用于 &'static [u8],而 String::as_bytes 不提供静态引用。您必须提供一些拥有的数据结构给 Bytes::from。我建议直接传递您的 text_owned 变量,因为 Bytes 实现了 From<String>:
pub async fn send_msg(online_users: Arc<Mutex<OnlineUsers>>, msg: &Message, from: &str) -> io::Result<()> {
let target_user = msg.args.get(0).ok_or(io::Error::from(io::ErrorKind::InvalidInput))?;
if let Content::Text(ref text) = msg.content {
let text_owned = text.clone();
let text_byte = Bytes::from(text_owned);
let mut online_users = online_users.lock().await;
online_users.send_to_user(target_user, text_byte).await;
}
Ok(())
}
英文:
Bytes::from is implemented for &'static [u8], whereas String::as_bytes does not give you a static reference. You must provide some owned data structure to Bytes::from. I'd opt for passing your text_owned variable directly, as Bytes implements From<String>:
pub async fn send_msg(online_users: Arc<Mutex<OnlineUsers>>, msg: &Message, from: &str) -> io::Result<()> {
let target_user = msg.args.get(0).ok_or(io::Error::from(io::ErrorKind::InvalidInput))?;
if let Content::Text(ref text) = msg.content {
let text_owned = text.clone();
let text_byte = Bytes::from(text_owned);
let mut online_users = online_users.lock().await;
online_users.send_to_user(target_user, text_byte).await;
}
Ok(())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论