在修补一个板条箱时,我自己隐藏了内部迭代器类型,但是作者说发布该类型是一项功能,最佳实践是为公开给公众的每个迭代器发布一个显式的包装器结构。 API。显然,Rust标准库为其所有迭代器执行此操作。
为什么这样做?更具体地说,如果实现与std::env::Args
兼容的类型,使用...的优缺点是什么?
// implement iterator compatible with std::env::Args
pub struct Args { // public
// pub(crate) ...
}
impl Iterator for Args {
// ...
}
pub fn args() -> Args {
// ...
// return Args
}
vs
// implement iterator compatible with std::env::Args
pub(crate) struct Args { // hidden (outside of crate)
// pub(crate) ...
}
impl Iterator for Args {
// ...
}
pub fn args() -> impl Iterator<Item = String> {
// ...
// return Args
}
答案 0 :(得分:8)
从来没有一个真正的最佳实践。
返回具体类型的原因包括:
您当前无法声明类型为impl Trait
的变量,因此必须推断出任何此类用法。出于相同的原因,不能轻易将它们放置在结构中。
与trentcl points out一样,impl Trait
无法有条件地实现特征。这对于Skip
之类的迭代器适配器来说很重要。
您声明“与std::env::Args
兼容”,但这是Args
实现的特征:
impl Iterator for Args {}
impl ExactSizeIterator for Args {}
impl DoubleEndedIterator for Args {}
impl Debug for Args {}
您的界面不允许使用这四个中的三个。作为一个例子,您的API的使用者不能再从后面进行迭代。您可以通过执行impl Iterator<Item = String> + DoubleEndedIterator + ExactSizeIterator + Debug
来解决此问题,但是无论如何在某种程度上您还是拥有自己的类型。如果您在现有迭代器上返回新类型,也可能会出现此问题,这就是为什么我想要更好的委托语法。
另请参阅C-NEWTYPE-HIDE API指南。
Rust标准库对其所有迭代器执行此操作
标准库中的迭代器是在impl Trait
存在之前创建的,因此没有其他选择。由于向后兼容,现在不能更改它们以不再返回具体类型。