考虑以下代码:
type ThingIter = dyn Iterator<Item = u64>;
trait Foo {
type ThingIter: Iterator<Item = u64>;
}
enum Bar<T: Foo> {
A(T::ThingIter),
B(ThingIter),
}
使用 Rust-1.68.2 进行编译,枚举臂 A
编译得很好(即,如果我注释掉 B
,它就会编译),但是枚举臂B
没有 - 我收到一条错误,表明 ThingIter
没有在编译时已知的大小。
为什么会有这种差异? T::ThingIter
的大小在编译时也无法得知(它可能是任意大小容器的迭代器)。另外,除了将其放入 Box
或获取引用之外,我该怎么做才能使外部 type
的行为与内部 type
类似(即,我可以毫无问题地将其放入枚举中)?
最佳答案
The size of
T::ThingIter
also cannot be known at compile time (it could be an iterator to an arbitrarily sized container).
T::ThingIter
确实有一个已知的大小,因为有一个 implicit + Sized
bound 。如果您还想接受未指定大小的类型,则必须明确选择退出。如果放松该约束,那么它也无法编译:
trait Foo {
type ThingIter: Iterator<Item = u64> + ?Sized;
}
结果:
error[E0277]: the size for values of type `<T as Foo>::ThingIter` cannot be known at compilation time
--> src/lib.rs:8:7
|
8 | A(T::ThingIter),
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
Also, short of putting it in a
Box
or taking a reference, what can I do to make the externaltype
behave similarly to the internaltype
(i.e., I can put it into anenum
without issues)?
这些是常见的解决方案。枚举变体不允许包含动态大小的字段。
如果迭代器在其他地方拥有,则 &
借用有效;否则,像 Box
、Rc
或 Arc
这样的自有指针是明智的。
关于rust - 特征中定义的类型与一般定义的类型之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76036891/