我想我需要一个与Sized
相反的特质。任何不是Sized
的东西都应该有这个特性。我需要这样做是为了避免在我的代码中针对大小和非大小类型不同地专门化另一个trait时发生冲突的实现。在这种情况下使用?Sized
是不起作用的,因为它会导致冲突的实现。
为此,我定义了一个auto-trait,然后在T: Sized
的情况下对T
进行了负impl。
我正在使用rust-nightly,在main.rs
中打开了auto_traits
和negative_impls
功能:
#![feature(auto_traits)]
#![feature(negative_impls)]
由于某些原因,dyn Any
没有实现Unsized
,尽管也没有实现Sized
。在自动实现中是否有一些隐含的Sized
需求?理想情况下,我希望每个类型都扩展Sized
或Unsized
,没有重叠。
use std::any::Any;
use static_assertions::assert_impl_one;
pub auto trait Unsized {}
impl<T> !Unsized for T
where
T: Sized
{
}
assert_not_impl_any!(dyn Any: Sized); // Succeeds! -> dyn Any is not Sized, as expected.
assert_impl_one!(dyn Any: Unsized); // Fails! -> dyn Any is not Unsized either??? It should be.
为什么trait Unsized
没有被实现为明显不是Sized
的东西?
删除否定实现会产生相同的Assert结果。dyn Any
仍然不是Unsized
。
1条答案
按热度按时间dsekswqp1#
auto-traits不会为dyn Traits实现,除非它们显式地选择它们(
dyn Any + Sync
,dyn Any + Unsized
)。原因是,如果我们考虑
dyn Trait
本身,auto traits几乎没有价值,因为它没有关于实际类型的信息。通常,我们想要的是底层类型实现auto-trait,而不是dyn Trait
本身。例如Sync
:我们无法判断dyn Any
是否是Sync
,因为我们不知道它包含什么数据。只有实际类型可以是Sync
或不是。这就是为什么dyn Trait
从不实现auto trait,除非用户明确表示它只会带来实现它的类型(dyn Trait + AutoTrait
)。