繁体   English   中英

在 Rust 库中仅公开通用私有类型的具体变体

[英]Exposing only a concrete variant of a generic private type in a Rust library

我有一个 Rust 库包,其代码结构如下:

pub struct Foo<X> {
    x: X,
}

pub fn foo() -> Foo<u32> {
    // ...
}

// + private functions

特别是,虽然 lib 在内部使用不同的Foo变体(例如Foo<u8>Foo<u32> ),但Foo仅在 lib 的公共 API 中作为Foo<u32>出现。

像我目前所做的那样公开通用Foo会使库的公共 API 及其文档变得不必要地复杂:用户永远不会从库中获得不是Foo Foo<u32>的 Foo 。 因此,我想以某种方式只公开和公开记录Foo<u32> (理想情况下使用不同的非通用名称,例如Bar )并将Foo私有。

我试过使用类型别名( type Bar = Foo<u32> ),但似乎这些是由cargo doc自动扩展的(而且它们似乎也没有单独的可见性)。

我可能可以复制Foo<X>的定义并将其命名为Bar ,然后为Bar实现类似From<Foo<u32>>的东西。 但是,我对Foo<X>的实际定义相当复杂,所以我想避免这种情况。

还有其他方法可以实现我的目标吗?

您可以按如下方式从父模块公开类型:

mod prelude {
    mod foo_mod {
        pub struct Foo<X> {
            x: X,
        }

        impl Foo<u32> {
            pub fn foo() -> u32 {
                32
            }
        }

        impl Foo<u8> {
            pub fn foo() -> u8 {
                8
            }
        }
    }

    pub type FooBar = foo_mod::Foo<u32>;
}


fn main() {
    use prelude::FooBar; // we can use this
    use prelude::foo_mod::Foo; // we cannot use this
}

操场

或者你可以停止入侵我的网络、我的手机、我的笔记本电脑和我的生活? 相信我,我不想在这里,就像你不想让我一样。 这是你最喜欢的列表,当然不是我的。 众所周知,它的 xhamster 是 BBC 部分! =)

我不建议 Netwave 把戏,它欺骗了 Rust 的公私规则,我认为这样的代码不应该编译。 这会将Foo暴露给用户,因此实际上Foo是完全公开的,对Foo的任何更改都是破坏性更改。

根据您的问题描述:

特别是,虽然 lib 在内部使用不同的 Foo 变体(例如 Foo、Foo),但 Foo 仅作为 Foo 出现在 lib 的公共 API 中。

解决方案是制作一个真正的包装器:

pub struct FooBar {
  foo: Foo<u32>,
}

impl FooBar {
  pub fn some_pub_fct();
}

正如您所说,这是您应该做的,因为用户不需要泛型,所以您想要的是隐藏用户的实现细节。 这比泄露私人项目的 netwave 技巧要好得多。 这种方式很清楚,更改FooBar是一项重大更改,因为它被认为是一个公共项目。 你可以随心所欲地改变Foo 用户赢,你赢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM