借用的值在结果 - 映射的通用结构中存在的时间不够长

发布于 2025-01-17 04:04:56 字数 712 浏览 2 评论 0原文

impl<'a, T> ClientDBMain<T>
where
    T: FromRow<'a, PgRow>,
{
    async fn query_one(&self, pool: &PgPool, query_raw: &str) -> Result<T, MyError> {
        let res = sqlx::query(query_raw)
            .fetch_one(pool)
            .await
            .map(|r: PgRow| {
                // error here
                T::from_row(&r).unwrap()
            })
            .map_err(|err| {
                // to save for brevity
            })?;
        Ok(res)
    }
}

map() 中的 r 存活时间不够长。

r 的寿命是多少?

如何解决这个问题呢?通过强制延长使用寿命,至少作为a?有什么办法可以管理吗?

impl<'a, T> ClientDBMain<T>
where
    T: FromRow<'a, PgRow>,
{
    async fn query_one(&self, pool: &PgPool, query_raw: &str) -> Result<T, MyError> {
        let res = sqlx::query(query_raw)
            .fetch_one(pool)
            .await
            .map(|r: PgRow| {
                // error here
                T::from_row(&r).unwrap()
            })
            .map_err(|err| {
                // to save for brevity
            })?;
        Ok(res)
    }
}

r in map() does not live long enough.

What is the life span of r?

How to solve this problem? By enforcing longer life time, at least as a? Is there any way to manage that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心在旅行 2025-01-24 04:04:57

您几乎肯定想要使用排名更高的特征界限:

impl<T> ClientDBMain<T>
where
    T: for<'a> FromRow<'a, PgRow>,
    // ^^^^^^^
{
    async fn query_one(&self, pool: &PgPool, query_raw: &str) -> Result<T, MyError> {
        ...

您的原始代码传达的是,如果该行具有特定的生命周期,则 T 只能从 PgRow 生成。外部生命周期不可能适合仅存在于该闭包内的 r。相反,for<'a> 引入了通用生命周期,本质上是说 T 为任何生命周期实现了 FromRow

You almost definitely want to use a higher-ranked trait bound:

impl<T> ClientDBMain<T>
where
    T: for<'a> FromRow<'a, PgRow>,
    // ^^^^^^^
{
    async fn query_one(&self, pool: &PgPool, query_raw: &str) -> Result<T, MyError> {
        ...

Your original code was communicating that T could only be made from a PgRow if the row had a specific lifetime. There is no way that an external lifetime would be appropriate for r which only lives within that closure. Instead, the for<'a> introduces a generic lifetime, essentially saying that T implements FromRow for any lifetime.

又怨 2025-01-24 04:04:57

r 似乎有一个'static 生命周期,但是由于它不会被移动,因此它会在 map.问题是 FromRow 可能会生成引用 r 的值,这意味着它不能比 r 更长寿。由于它的执行方式可能是通过 'a 实现的,因此您可以通过要求 T: FromRow<'static, PgRow> 来解决此问题。如果结果类型具有'static 生命周期,那么它将不依赖于r 的生命周期。

impl<T> ClientDBMain<T>
where
    T: FromRow<'static, PgRow>,
{
    async fn query_one(&self, pool: &PgPool, query_raw: &str) -> Result<T, MyError> {
        let res = sqlx::query(query_raw)
            .fetch_one(pool)
            .await
            .map(|r: PgRow| {
                // error here
                T::from_row(&r).unwrap()
            })
            .map_err(|err| {
                // to save for brevity
            })?;
        Ok(res)
    }
}

r appears to have a 'static lifetime, however since it does not get moved it will be dropped upon falling out of scope at the end of the map. The issue is that FromRow may produce a value referencing r meaning it can not outlive r. Since it appear that the way it does this is probably via 'a, you can probably fix this by requiring T: FromRow<'static, PgRow>. If the resulting type has a 'static lifetime then it would not be reliant of the lifetime of r.

impl<T> ClientDBMain<T>
where
    T: FromRow<'static, PgRow>,
{
    async fn query_one(&self, pool: &PgPool, query_raw: &str) -> Result<T, MyError> {
        let res = sqlx::query(query_raw)
            .fetch_one(pool)
            .await
            .map(|r: PgRow| {
                // error here
                T::from_row(&r).unwrap()
            })
            .map_err(|err| {
                // to save for brevity
            })?;
        Ok(res)
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文