如何声明仅接受其他类型特定子集的类型?
关于你构想的Rust枚举与Haskell类似特性的说明
你构想的这段Rust代码试图让枚举变体接受特定值的子集:
enum Foo { FirstThreeChars('a' | 'b' | 'c'), Bools(0 | 1), }
首先要明确,当前Rust并不支持这种语法。你想要的是让枚举变体的关联值被限定在一个固定的小型集合里,这种特性在Haskell中确实有对应的实现方式。
在Haskell中实现类似效果
Haskell可以通过定义精确的代数数据类型来限定值范围,比如:
data FirstThreeChars = A | B | C deriving (Show, Eq) data Bools = Zero | One deriving (Show, Eq) data Foo = FirstThreeChars FirstThreeChars | Bools Bools deriving (Show, Eq)
这种方式能严格约束每个变体只能接受指定的子集值,还可以通过类型类实现自定义类型与原生字符、数值类型的转换。
在Rust中实现类似需求的替代方案
如果要在Rust里达到同样的约束效果,有两种常用思路:
自定义枚举嵌套:先定义对应有限值的枚举,再作为目标枚举变体的关联值
#[derive(Debug, Clone, Copy)] enum FirstThreeChars { A, B, C, } #[derive(Debug, Clone, Copy)] enum Bools { Zero, One, } enum Foo { FirstThreeChars(FirstThreeChars), Bools(Bools), }这种方式类型安全性最高,但需要手动处理和原生
char/u8类型的转换逻辑。构造函数验证:保留原生类型,通过构造函数确保值符合要求
enum Foo { FirstThreeChars(char), Bools(u8), } impl Foo { fn new_first(c: char) -> Option<Self> { matches!(c, 'a' | 'b' | 'c').then_some(Self::FirstThreeChars(c)) } fn new_bool(b: u8) -> Option<Self> { matches!(b, 0 | 1).then_some(Self::Bools(b)) } }这种方式保留了原生类型的便利性,但依赖构造函数来保证值的合法性,直接创建枚举实例仍可能传入非法值。
内容的提问来源于stack exchange,提问作者Robert Byrne
相关产品推荐
相关产品推荐

