板条箱级别的可见性

时间:2015-06-12 18:14:57

标签: interface rust encapsulation

我有两种类型,每种都有一系列支持功能;这两种类型的全部内容应该是私有的(在我的例子中,它们是C中对象的可变指针)。这两种类型在概念上是不同的,所以我将它们放在不同的模块中......

pub mod client {
    pub struct Client {
        // private internals
    }
    // Lots of code.
}
pub mod collection {
    pub struct Collection {
        // private internals
    }
    // Lots of code.
}

(在我的实际案例中,mod clientmod collection是单独的文件,即client.rscollection.rs。)

client.rs需要创建Collection;然而,它不可能,因为内部是私人的。任何编写函数的尝试都会遇到同样的问题:函数需要在collection.rs中(访问Collection的私有成员,但需要pub才能client.rs pub 1}}可以访问它...但现在它也pub到整个世界。

我真正喜欢的是某种箱子级别的可见度,或者是对朋友的一种方式"这个结构到另一个模块。 (否则,包中的getProject lically可见内容并不能代表API,这看起来很愚蠢。)

2 个答案:

答案 0 :(得分:3)

Collection移至新的私人模块(例如collection_impl)。在该模块中添加公共函数以创建Collection。使用Collectioncollection(公开)重新导出pub use

您可以在箱子中使用collection_impl,但由于它是私人的,因此其他包装箱不能使用它。但是,通过在模块Collection中重新导出collection,其他包可以通过此路径使用Collection

pub mod client {
    use super::collection;
    use super::collection_impl;

    pub struct Client {
        p: i32
    }

    /* this could also be a method on Client */
    pub fn make_collection(client: &Client) -> collection::Collection {
        collection_impl::new_collection(42)
    }
}

mod collection_impl {
    pub struct Collection {
        p: i32
    }

    pub fn new_collection(p: i32) -> Collection {
        Collection { p: p }
    }
}

pub mod collection {
    use super::collection_impl;
    pub use collection_impl::Collection;
}

答案 1 :(得分:2)

如果你比较Rust和C ++,你会注意到Rust没有:

  • protected
  • friend

这是一个刻意的设计,没有其他选择。在Rust中,某些东西是私有的或公共的,因此你不必在代码库周围跳转来知道是否存在不变量。

因此,解决方案是:

  • 制作pub fn new函数以创建Collection
  • 强化此功能,使全世界使用它是完全安全的

这实际上是好的设计;如果一个 struct应该负责维护Collection的不变量,那肯定是Collection本身。将此责任委托给另一个箱子似乎是危险的。