Scala 3中如何编写支持多数值类型的通用泛型数值方法
Scala 3 实现跨数值类型通用方法方案
Scala 3 并未移除隐式解析的核心能力,只是将Scala 2中语义模糊的implicit关键字拆分为了更清晰的given(定义隐式实例)、using(声明隐式参数)语法,针对数值类型的通用抽象,直接复用标准库提供的Numeric类型类即可实现需求,不需要手动编写各数值类型的适配逻辑。
基础可运行实现
直接通过上下文参数声明当前泛型T需要满足Numeric类型类约束,调用Numeric提供的数值操作方法即可:
import scala.math.Numeric def add2[T](number: T)(using n: Numeric[T]): T = n.plus(number, n.fromInt(2))
该实现原生支持所有内置数值类型,直接调用即可自动适配类型:
add2(1) // 返回Int类型结果 3 add2(3.5f) // 返回Float类型结果 5.5 add2(4.2) // 返回Double类型结果 6.2 add2(100L) // 返回Long类型结果 102
贴近原生运算符的写法
如果想直接写number + 2的原生运算符形式,只需要导入Numeric提供的扩展方法即可:
import scala.math.Numeric import scala.math.Numeric.Implicits._ def add2[T](number: T)(using Numeric[T]): T = number + 2
更简洁的语法糖
Scala 3 提供了上下文绑定的简写语法,可以进一步简化泛型声明,省略显式的using参数写法,这也是日常开发最推荐的写法:
import scala.math.Numeric import scala.math.Numeric.Implicits._ def add2[T: Numeric](number: T): T = number + 2
[T: Numeric]的含义是:泛型T必须存在对应Numeric[T]的上下文实例,编译器会自动完成隐式实例的查找和传入,和前两种写法的编译结果完全一致。
和Scala 2隐式方案的对应关系
- Scala 2中
def f[T](implicit ev: Numeric[T])的隐式参数声明,对应Scala3的def f[T](using Numeric[T]) - Scala 2中用
implicit val/object定义的隐式实例,对应Scala3的given定义,标准库已经为Int、Float、Double等所有数值类型预定义了对应的Numeric实例,不需要手动编写 - 该实现是编译期类型安全的,如果传入非数值类型,编译阶段就会直接报错,不会产生运行时异常
内容的提问来源于stack exchange,提问作者PopKernel
相关产品推荐
相关产品推荐

