如何在Scala 3中用opaque定义基于整数子集的Even类型
Scala 3 基于判断函数实现Even类型的方案
首先得明确:Scala 3的opaque type本质是编译期的类型别名,运行时会擦除成底层类型,它本身没法直接绑定过滤函数来限制定义域。但我们可以结合伴生对象的工厂方法,用你提供的isEven函数控制Even类型的创建,实现类型安全,完全符合“以函数为构建块”的需求,无需复杂的newtype或Refined Types。
具体实现代码
// 定义判断偶数的核心函数 val isEven: Int => Boolean = _ % 2 == 0 // 定义opaque类型Even,底层复用Int的结构 opaque type Even = Int // 伴生对象封装Even的创建逻辑,用isEven做校验 object Even { // 安全创建Even实例:仅当输入Int满足isEven时返回Some[Even] def apply(n: Int): Option[Even] = if isEven(n) then Some(n) else None // 可选:提供从Even转回Int的方法 def toInt(even: Even): Int = even // 提取器,支持模式匹配场景 def unapply(even: Even): Option[Int] = Some(even) } // 使用示例 val validEven = Even(4) // 结果:Some(4): Option[Even] val invalidEven = Even(3) // 结果:None: Option[Even] // 模式匹配用法 validEven match { case Even(num) => println(s"$num 是合法的偶数类型实例") case None => println("输入不是偶数,无法创建Even类型") }
关于直接用type Even = ???的说明
如果直接写type Even = Int,这只是普通的类型别名,没有任何类型安全保证——任何Int都可以直接赋值给Even类型变量,完全起不到“限定为偶数”的作用。所以更推荐上面的opaque类型+工厂方法的组合,既轻量又能通过isEven函数严格控制类型的合法范围。
内容的提问来源于stack exchange,提问作者Jimmy Isaac
相关产品推荐
相关产品推荐

