在Haskell中,我可以做类似的事情(示例改编自Learn You A Haskell)

module Shapes (
    Shape,
    newCircle,
    newRectangle,
    ... -- other functions for manipulating the shapes
)

data Shape = Circle Int Int Float       -- x, y, radius
           | Rectangle Int Int Int Int  -- x1, y1, x2, y2

newCircle :: Float -> Shape
newCircle r = Circle 0 0 r

newRectangle :: Int -> Int -> Shape
newRectangle w h = Rectangle 0 0 w h

... -- other functions for manipulating the shapes

这将允许我只公开Shape类型以及newCirclenewRectangle函数.

rust 迹是否也有类似的作用?

推荐答案

在一般意义上,没有;Rust没有私有枚举构造函数.枚举是纯粹的公共事物.

然而, struct 不是这样的,因此您可以将它们组合起来,使变体纯粹成为一个实现细节:

// This type isn’t made public anywhere, so it’s hidden.
enum ShapeInner {
    // Oh, and let’s use struct variants ’cos they’re cool.
    Circle {
        x: i32,
        y: i32,
        radius: f64,
    },
    Rectangle {
        x1: i32,
        y1: i32,
        x2: i32,
        y2: i32,
    },
}

// Struct fields are private by default, so this is hidden.
pub struct Shape(ShapeInner);

impl Shape {
    pub fn new_circle(radius: f64) -> Shape {
        Shape(Circle { x: 0, y: 0, radius: radius })
    }

    pub fn new_rectangle(width: i32, height: i32) -> Shape {
        Shape(Rectangle { x1: 0, y1: 0, x2: width, y2: height })
    }

    // “match self.0 { Circle { .. } => …, … }”, &c.
}

不过,作为一种普遍做法,我建议不要这样做.

Rust相关问答推荐

Rust为什么应用于引用的操作符可以强制,而具有显式类型的let则不能?

带扫描的铁 rust 使用滤镜

编译项目期间使用Cargo生成时出现rustc错误

如何格式化传入Rust中mysql crate的Pool::new的字符串

无法将记录器向下转换回原始 struct

默认特征实现中的生命周期问题

如何循环遍历0..V.len()-1何时v可能为空?

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

为什么 vec![Vec::with_capacity(n)] 为子向量创建 0 容量?

要求类型参数有特定的大小?

在使用粗粒度锁访问的数据 struct 中使用 RefCell 是否安全?

Rust 如何将链表推到前面?

将多维数组转换为切片

‘&T as *const T as *mut T’ 在 ‘static mut’ 项目中合适吗?

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

是否可以通过可变引用推进可变切片?

我的 Axum 处理程序无法编译:未实现 IntoResponse 特征

如何在 Rust 中将 UTF-8 十六进制值转换为 char?

如何在没有 `make_contiguous()` 的情况下对 VecDeque 进行排序或反转?

如何在 Rust 中构建一个 str