Scala如何合并Int与Double类型的数值范围生成函数
解决方案
你可以通过自定义类型类的方式,在不强制类型转换的前提下合并这两个函数,同时保留Int和Double各自的范围创建逻辑:
步骤1:定义范围构建的类型类
这个类型类负责定义不同数值类型如何生成对应的范围:
trait RangeBuilder[T] { def build(min: T, max: T, step: T): Iterable[T] }
步骤2:为Int和Double实现类型类实例
分别为Int和Double编写范围创建的具体逻辑,复用你原来的to...by语法:
object RangeBuilder { // Int类型的范围构建器 implicit val intRangeBuilder: RangeBuilder[Int] = (min, max, step) => min to max by step // Double类型的范围构建器 implicit val doubleRangeBuilder: RangeBuilder[Double] = (min, max, step) => min to max by step }
步骤3:编写合并后的泛型函数
依赖上面的类型类隐式实例,实现统一的逻辑:
import RangeBuilder._ private def getRange[T](minLimit: T, maxLimit: T, step: T)(implicit rb: RangeBuilder[T]): List[Something] = { rb.build(minLimit, maxLimit, step) .map(_.toString) .map( // 这里放你原来的公共逻辑 ) .toList }
调用方式
直接传入Int或Double参数即可,Scala会自动匹配对应的隐式构建器:
// 调用Int版本 val intResult = getRange(1, 10, 2) // 调用Double版本 val doubleResult = getRange(0.5, 5.5, 1.0)
为什么这个方案符合你的需求?
- 完全合并了重复逻辑,只保留一个函数
- 不需要任何类型强制转换,Int和Double各自使用原生的范围生成逻辑
- 可以精准控制支持的类型(仅Int和Double,不会意外支持其他Numeric子类)
如果你使用的是Scala 3,可以用更简洁的given/using语法实现同样的逻辑:
trait RangeBuilder[T]: def build(min: T, max: T, step: T): Iterable[T] object RangeBuilder: given RangeBuilder[Int] with def build(min: Int, max: Int, step: Int): Iterable[Int] = min to max by step given RangeBuilder[Double] with def build(min: Double, max: Double, step: Double): Iterable[Double] = min to max by step private def getRange[T](minLimit: T, maxLimit: T, step: T)(using rb: RangeBuilder[T]): List[Something] = rb.build(minLimit, maxLimit, step) .map(_.toString) .map(/* 公共逻辑 */) .toList
内容的提问来源于stack exchange,提问作者Emilia Paredes
相关产品推荐
相关产品推荐

