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