英文:
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(())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论