在 Rc 上实现 Trait 不会解析为 Rc<dyn Trait>,发现以下实现 <Rc<T> 作为 Trait>
Implementation of a Trait over a Rc doesn't resolve to a Rc<dyn Trait>, following implementations were found <Rc<T> as Trait>
我试图将 DST 包装在 Rc
上,目的是克隆它并从代码的各个部分访问它,但编译时出现以下错误。
这是错误的最小可重现示例 (playground):
use std::rc::Rc;
trait Trait<'a> {
fn return_hello(&self) -> &'a str;
}
impl<'a, F> Trait<'a> for F
where
F: Fn() -> &'a str
{
fn return_hello(&self) -> &'a str {
self()
}
}
impl<'a, T> Trait<'a> for Rc<T>
where
T: Trait<'a>
{
fn return_hello(&self) -> &'a str {
(**self).return_hello()
}
}
fn caller<'a, T>(t: T)
where
T: Trait<'a>
{
print!("{}\n", t.return_hello());
}
fn main() {
fn test1<'a>() -> &'a str {
"Hello from function"
}
let test2 = move || "hello from closure";
fn f<'a>() -> &'a str {
"Hello from Rc"
}
let test3: Rc<dyn Trait<'_>> = Rc::new(f);
caller(test1);
caller(test2);
caller(test3);
}
给出:
error[E0277]: the trait bound `Rc<dyn Trait<'_>>: Trait<'_>` is not satisfied
--> src/main.rs:45:12
|
25 | fn caller<'a, T>(t: T)
| ------ required by a bound in this
26 | where
27 | T: Trait<'a>
| --------- required by this bound in `caller`
...
45 | caller(test3);
| ^^^^^ the trait `Trait<'_>` is not implemented for `Rc<dyn Trait<'_>>`
|
= help: the following implementations were found:
<Rc<T> as Trait<'a>>
你的 impl for Rc<T>
有一个隐含的要求 T: Sized
,就像你写的:
impl<'a, T> Trait<'a> for Rc<T>
where
T: Trait<'a> + Sized //The latter is implicit
但是当你想将它应用到 Rc<dyn Trait<'a>>
时,类型 T
是 dyn Trait<'a>
,而不是 Sized
,所以它不适用。
解决方案是添加 + ?Sized
以放宽该要求 (playground):
impl<'a, T> Trait<'a> for Rc<T>
where
T: Trait<'a> + ?Sized
既然你喜欢它,你也可以将它添加到另一个 impl
:
impl<'a, F> Trait<'a> for F
where
F: Fn() -> &'a str + ?Sized
因此它也适用于 dyn Fn() -> &'a str
。
在 Rc<T>
对 Trait
的实现中,T
有一个隐式绑定 Sized
(source) 因此,实现Rc<T>
只会解析为 Sized
类型。简单的告诉T
“may not be sized”就可以解决问题,所以加一个?Sized
.
impl<'a, T> Trait<'a> for Rc<T>
where
T: ?Sized + Trait<'a>
{
fn return_hello(&self) -> &'a str {
(**self).return_hello()
}
}
我试图将 DST 包装在 Rc
上,目的是克隆它并从代码的各个部分访问它,但编译时出现以下错误。
这是错误的最小可重现示例 (playground):
use std::rc::Rc;
trait Trait<'a> {
fn return_hello(&self) -> &'a str;
}
impl<'a, F> Trait<'a> for F
where
F: Fn() -> &'a str
{
fn return_hello(&self) -> &'a str {
self()
}
}
impl<'a, T> Trait<'a> for Rc<T>
where
T: Trait<'a>
{
fn return_hello(&self) -> &'a str {
(**self).return_hello()
}
}
fn caller<'a, T>(t: T)
where
T: Trait<'a>
{
print!("{}\n", t.return_hello());
}
fn main() {
fn test1<'a>() -> &'a str {
"Hello from function"
}
let test2 = move || "hello from closure";
fn f<'a>() -> &'a str {
"Hello from Rc"
}
let test3: Rc<dyn Trait<'_>> = Rc::new(f);
caller(test1);
caller(test2);
caller(test3);
}
给出:
error[E0277]: the trait bound `Rc<dyn Trait<'_>>: Trait<'_>` is not satisfied
--> src/main.rs:45:12
|
25 | fn caller<'a, T>(t: T)
| ------ required by a bound in this
26 | where
27 | T: Trait<'a>
| --------- required by this bound in `caller`
...
45 | caller(test3);
| ^^^^^ the trait `Trait<'_>` is not implemented for `Rc<dyn Trait<'_>>`
|
= help: the following implementations were found:
<Rc<T> as Trait<'a>>
你的 impl for Rc<T>
有一个隐含的要求 T: Sized
,就像你写的:
impl<'a, T> Trait<'a> for Rc<T>
where
T: Trait<'a> + Sized //The latter is implicit
但是当你想将它应用到 Rc<dyn Trait<'a>>
时,类型 T
是 dyn Trait<'a>
,而不是 Sized
,所以它不适用。
解决方案是添加 + ?Sized
以放宽该要求 (playground):
impl<'a, T> Trait<'a> for Rc<T>
where
T: Trait<'a> + ?Sized
既然你喜欢它,你也可以将它添加到另一个 impl
:
impl<'a, F> Trait<'a> for F
where
F: Fn() -> &'a str + ?Sized
因此它也适用于 dyn Fn() -> &'a str
。
在 Rc<T>
对 Trait
的实现中,T
有一个隐式绑定 Sized
(source) 因此,实现Rc<T>
只会解析为 Sized
类型。简单的告诉T
“may not be sized”就可以解决问题,所以加一个?Sized
.
impl<'a, T> Trait<'a> for Rc<T>
where
T: ?Sized + Trait<'a>
{
fn return_hello(&self) -> &'a str {
(**self).return_hello()
}
}