代码之家  ›  专栏  ›  技术社区  ›  rivy

在板条箱的API中发布具体类型而不是“impl trait”有什么好处?

  •  5
  • rivy  · 技术社区  · 7 年前

    在修补一个板条箱时,我自己承担了隐藏内部迭代器类型的责任,但是作者说发布该类型是一个特性,最佳实践是为公共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
    }
    

    // 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
    }
    
    1 回复  |  直到 7 年前
        1
  •  9
  •   Shepmaster Tim Diekmann    7 年前

    从来没有一个真正的最佳实践。

    返回混凝土类型的原因包括:

    1. 当前不能声明类型为的变量 impl Trait

    2. 不能将固有方法添加到 返回类型。例如, Chars as_str

    3. 作为 trentcl points out 内含性状 无法有条件地实现特性。这对于迭代器适配器(如 Skip .

    4. 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 但在某个时刻,你实际上有你自己的类型。如果在现有迭代器上返回一个newtype,这个问题也是可能的,这就是为什么我需要更好的委托语法。

    C-NEWTYPE-HIDE API指南。

    Rust标准库对所有迭代器都这样做

    标准库中的迭代器是以前创建的 他们就这样存在着 别无选择 . 由于向后兼容,现在不能将它们更改为不再返回具体类型。

    推荐文章