Scala如何定义方法签名仅允许传入仅含数值类型的任意嵌套List
实现方案
核心思路是通过递归类型类在编译期校验任意嵌套List的所有叶子节点都是数值类型,从根源上禁止非数值参数传入。你当前的实现依赖运行时模式匹配,上层参数用了无约束的泛型,所以无法触发编译报错,改用类型类约束即可解决。
完整实现(Scala 3版本)
// 定义递归类型类:证明类型T是合法的嵌套数值结构(要么是数值,要么是元素符合要求的List) trait NestedNumeric[T]: def flattenAndSum(t: T): Double // 基础case:所有支持Numeric的数值类型直接实现求和逻辑 given [T: Numeric]: NestedNumeric[T] with def flattenAndSum(t: T): Double = summon[Numeric[T]].toDouble(t) // 递归case:List的元素如果符合NestedNumeric要求,整个List也符合 given [A: NestedNumeric]: NestedNumeric[List[A]] with def flattenAndSum(list: List[A]): Double = list.foldLeft(0.0)((sum, elem) => sum + summon[NestedNumeric[A]].flattenAndSum(elem)) // 最终的sum方法,输入List的元素必须满足NestedNumeric约束 def sum[T: NestedNumeric](list: List[T]): Double = summon[NestedNumeric[List[T]]].flattenAndSum(list)
测试效果
合法输入(编译通过,正常运行)
// 仅含数值的嵌套List val validInput = List(List(1, 2, 3), 3.0, List(2.32, 6.36, List(List(1)))) println(sum(validInput)) // 输出19.68
非法输入(直接编译报错)
// 包含Boolean的输入 val invalidInput1 = List(List(1, 2, 3), 3.0, false, List(2.32, 6.36, List(List(1)))) sum(invalidInput1) // 编译失败:找不到Boolean类型对应的NestedNumeric实例 // 包含String、Option的输入 val invalidInput2 = List(List(1, 2, 3), 3.0, false, List(2.32, 6.36, List(List(1, "", Some(false))))) sum(invalidInput2) // 编译失败
Scala 2适配说明
如果使用Scala 2,把given/using语法替换为隐式值和隐式参数即可,核心逻辑完全一致。
内容的提问来源于stack exchange,提问作者Artem
相关产品推荐
相关产品推荐

