Rust 我可以声明不应该期望给定特性的实现大小吗?

Rust 我可以声明不应该期望给定特性的实现大小吗?,rust,traits,Rust,Traits,我定义了一个traitFoo,为[u32]实现了这个trait,并编写了一个函数bar,将这个trait作为参数(): 我可以用T:Foo+?Sized来修复它,但是对于每个需要Foo的函数,我都必须这样做,这是一种痛苦 我是否可以一次性声明Foo的实现不应该是大小的?我在第1行尝试了trait Foo:?size,但编译器对此表示不满 这个问题和我的不一样。在这个问题中,Foo参数被移动,因此编译器希望在编译时知道其大小是正常的。在我的例子中,参数是一个引用,因此不需要调整它的大小——但编译器

我定义了一个trait
Foo
,为
[u32]
实现了这个trait,并编写了一个函数
bar
,将这个trait作为参数():

我可以用
T:Foo+?Sized
来修复它,但是对于每个需要
Foo
的函数,我都必须这样做,这是一种痛苦

我是否可以一次性声明
Foo
的实现不应该是
大小的
?我在第1行尝试了
trait Foo:?size
,但编译器对此表示不满

这个问题和我的不一样。在这个问题中,
Foo
参数被移动,因此编译器希望在编译时知道其大小是正常的。在我的例子中,参数是一个引用,因此不需要调整它的大小——但编译器仍然隐式地假定它是引用,除非明确地告诉它(使用
+?size
)。我想改变的是这个隐含的假设,对于这个特殊的特性。

为什么编译器会抱怨
trait Foo:?size
? 当你说每一个
Foo
都是
size
的时候,你在某种程度上对自己隐瞒了真相。是的,每个
Foo
都是
大小的
,但实际上每个类型在某一点上都有一个给定的大小。真正重要的信息是,你没有说这个尺寸有多大

在这种情况下,您需要一个大小合适的
[u32]

impl<'a> Foo for &'a [u32] {
    fn foo(&self) -> u32 {
        self[0]
    }
}

fn bar<T>(f: T) -> u32
where
    T: Foo,
{
    f.foo() + 1
}
error[E0277]:未满足特征绑定“[u32]:std::marker::Sized”
|
|[u32]的impl Foo{
|^^^`[u32]`在编译时没有已知的常量大小
|
=帮助:`[u32]未实现特性`std::marker::Sized``
欲了解更多信息,请咨询

既然我们只有一个参考,为什么不能取消
t
的大小? 让我再次引用

默认情况下,函数上的所有泛型类型都隐式绑定了
大小
,而不管它们是如何使用的。您需要使用
?大小
显式选择不满足该要求

这将解决您的问题:

fn bar<T>(f: &T) -> u32
where
    T: Foo + ?Sized,
{
    f.foo() + 1
}

在这种特殊情况下,您甚至可以对
Foo
的实现进行一般化,它将在
Vec
s和数组以及对这些类型的引用上工作:

impl<T: AsRef<[u32]>> Foo for T {
    fn foo(&self) -> u32 {
        self.as_ref()[0]
    }
}

请注意,最后一个符号有点争议,但我不会在这个答案中深入讨论。谢谢你的回答。关于第一部分,我想你没有领会我的意思:我没有试图强制执行Foo:size,但相反,Foo:?size(即“Foo可以不调整大小”)。关于第二部分,我有一个实现Foo的想法&[u32]但是我必须通过一个&&[u32]对于
bar
,这似乎有点尴尬…@Pierre Antoine那么答案解决了你的问题了吗?不完全是:它使特定的示例得以编译,但我的目标是让编译器知道,在我将类型参数绑定到Foo的任何地方都应该使用Foo+?size。显然,这是不可能的…:-(@Pierre Antoine注意到,Tim的第二个示例将
bar
改为
T
,而不是
&T
;因此,不需要
&
T
变成
&u32]
)。
impl<T: AsRef<[u32]>> Foo for T {
    fn foo(&self) -> u32 {
        self.as_ref()[0]
    }
}
fn bar(f: impl Foo) -> u32 {
    f.foo() + 1
}