为什么可以box< dyn特征>用& mut特征作为参数启用函数

发布于 2025-01-22 10:38:24 字数 1903 浏览 2 评论 0原文

我敢肯定,以前已经问过,但没有遇到一个问题,可以捕捉这里的精确情况。我有以下代码:

let mut pool: Box<dyn redis::aio::ConnectionLike> = <...>
redis::cmd(COMMAND)
    .arg(LIST)
    .arg(value)
    .query_async(&mut pool)
    .await
    .unwrap();

这返回错误:

error[E0277]: the trait bound `std::boxed::Box<dyn redis::aio::ConnectionLike>: redis::aio::ConnectionLike` is not satisfied
   --> svix-server/src/queue/redis.rs:66:30
    |
66  |                 .query_async(&mut pool)
    |                  ----------- ^^^^^^^^^ the trait `redis::aio::ConnectionLike` is not implemented for `std::boxed::Box<dyn redis::aio::ConnectionLike>`
    |                  |
    |                  required by a bound introduced by this call
    |

问题1-为什么错误说该性状未针对box&lt; dyn redis :: aio :: aio :: connection like&gt;?至少不应该说&amp; box ...吗?

无论如何,如果我尝试将pool.as_mut()转换为query_async,我会收到此错误:

error[E0277]: the size for values of type `dyn redis::aio::ConnectionLike` cannot be known at compilation time
   --> svix-server/src/queue/redis.rs:66:30
    |
66  |                 .query_async(pool.as_mut())
    |                  ----------- ^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |                  |
    |                  required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `dyn redis::aio::ConnectionLike`

问题2-为什么sip sip sized必需这里? Rust中的参考不是始终大小吗?

问题3-是否有任何方法可以将dyn Connection传递给

query_async方法,例如

#[inline]
#[cfg(feature = "aio")]
pub async fn query_async<C, T: FromRedisValue>(&self, con: &mut C) -> RedisResult<T>
where
    C: crate::aio::ConnectionLike,
{
   ...
}

I'm sure this has been asked previously but haven't encountered a question that captures the precise scenario here. I have the following code:

let mut pool: Box<dyn redis::aio::ConnectionLike> = <...>
redis::cmd(COMMAND)
    .arg(LIST)
    .arg(value)
    .query_async(&mut pool)
    .await
    .unwrap();

This returns the error:

error[E0277]: the trait bound `std::boxed::Box<dyn redis::aio::ConnectionLike>: redis::aio::ConnectionLike` is not satisfied
   --> svix-server/src/queue/redis.rs:66:30
    |
66  |                 .query_async(&mut pool)
    |                  ----------- ^^^^^^^^^ the trait `redis::aio::ConnectionLike` is not implemented for `std::boxed::Box<dyn redis::aio::ConnectionLike>`
    |                  |
    |                  required by a bound introduced by this call
    |

Question 1 -- Why does the error say the trait is not implemented for Box<dyn redis::aio::ConnectionLike>? Shouldn't it at least say &Box...?

Regardless, if I instead try to pass pool.as_mut() to query_async, I get this error:

error[E0277]: the size for values of type `dyn redis::aio::ConnectionLike` cannot be known at compilation time
   --> svix-server/src/queue/redis.rs:66:30
    |
66  |                 .query_async(pool.as_mut())
    |                  ----------- ^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |                  |
    |                  required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `dyn redis::aio::ConnectionLike`

Question 2 -- Why is Sized required here? Isn't a reference in Rust always Sized?

Question 3 -- Is there any way to to pass a dyn ConnectionLike to this

The query_async method, for reference looks like this:

#[inline]
#[cfg(feature = "aio")]
pub async fn query_async<C, T: FromRedisValue>(&self, con: &mut C) -> RedisResult<T>
where
    C: crate::aio::ConnectionLike,
{
   ...
}

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

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

发布评论

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

评论(2

你是暖光i 2025-01-29 10:38:24

问题1-为什么错误说该性状未针对box&lt; dyn redis :: aio :: connection&gt;?至少不应该说&amp; box ...?

不,因为引用不是通用类型c的一部分。 Rust并未命名全部类型,它仅命名两种类型的部分不匹配。该函数接受&amp; mut cc是匹配的通用部分。 box类型是用c替换的,并且无法实现此特征。

问题2-为什么此处需要大小? Rust中的参考不是始终大小

参考确实是大小,但是如上所述,我们与类型mut dyn redis :: aio :: connection like相对于&amp; mut c 。这将导致cdyn redis :: aio ::类似连接

在Rust中,通用类型具有大小 bond 默认情况下。您必须明确指定sized bunditi此功能没有。因此,c必须实现大小dyn redis :: aio :: connection like否。

问题3-是否有任何方法可以将dyn Connection传递给此

,但不是直接的。您需要实现一种包装引用到dyn Connection> 或box&lt; dyn Connection&gt;的类型。像:

struct BoxedConnectionLike(Box<dyn ConnectionLike>);

impl ConnectionLike for BoxedConnectionLike {
    // Implement proxy functions for the trait.
}

Question 1 -- Why does the error say the trait is not implemented for Box<dyn redis::aio::ConnectionLike>? Shouldn't it at least say &Box...?

No, because the reference is not part of the generic type C. Rust doesn't name the entire type, it only names the parts of the two types that don't match. The function accepts &mut C and C is the generic part being matched. The Box type is what is substituted for C, and it doesn't implement this trait.

Question 2 -- Why is Sized required here? Isn't a reference in Rust always Sized?

A reference is indeed Sized, but as noted above we are matching the type &mut dyn redis::aio::ConnectionLike against &mut C. This results in C being dyn redis::aio::ConnectionLike.

In Rust, generic types have the Sized bound by default. You have to explicitly specify the ?Sized bound to relax this, which the author of this function did not do. Therefore, C must implement Sized, and dyn redis::aio::ConnectionLike does not.

Question 3 -- Is there any way to to pass a dyn ConnectionLike to this

Possibly, but not directly. You would need to implement a type that wraps either a reference-to-dyn ConnectionLike or a Box<dyn ConnectionLike> and pass that instead. Something like:

struct BoxedConnectionLike(Box<dyn ConnectionLike>);

impl ConnectionLike for BoxedConnectionLike {
    // Implement proxy functions for the trait.
}
戒ㄋ 2025-01-29 10:38:24

为什么在此处需要大小?

pub async fn query_async<C, T: FromRedisValue>(&self, con: &mut C) -> RedisResult<T>
where
    C: crate::aio::ConnectionLike,

Rust中的所有类型参数均具有隐式尺寸绑定,除非它们选择退出 - 编译器的作用为c:sizied sized已指定。

可能会推广此代码以允许允许使用的类型(书面c:?siped);我不知道。

Rust中的参考不是总是尺寸的吗?

是的,但是隐式界限是在指称上,c

是否有任何方法可以将Dyn Connection换到此

,您需要定义或使用现有的类型,该类型实现了connection like特征,包含 a a dyn Connection,然后将可变的引用传递给该类型。

最清洁的方法是通过实现实现来使用框本身,

impl<C: ?Sized> ConnectionLike for Box<C>
where
    C: ConnectionLike
{ ... }

但是,只有定义性状的板条箱才能添加impl

Why is Sized required here?

pub async fn query_async<C, T: FromRedisValue>(&self, con: &mut C) -> RedisResult<T>
where
    C: crate::aio::ConnectionLike,

All type parameters in Rust have an implicit Sized bound unless they opt out — the compiler acts as if C: Sized was specified.

Possibly this code could be generalized to allow unsized types (written C: ?Sized); I don't know.

Isn't a reference in Rust always Sized?

Yes, but the implicit bound is on the referent, C.

Is there any way to to pass a dyn ConnectionLike to this

You need to define, or use an existing, type which implements the ConnectionLike trait and contains a dyn ConnectionLike, then pass a mutable reference to that type.

The cleanest approach is to use Box itself, by having the implementation

impl<C: ?Sized> ConnectionLike for Box<C>
where
    C: ConnectionLike
{ ... }

But, only the crate defining the trait can add that impl.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文