Scala实现参数化mean函数编译报错:/不是类型参数A的成员
问题
尝试实现支持泛型的Seq集合均值计算函数时,编译抛出value / is not a member of type parameter A错误,原始实现代码如下:
def mean[A](xs: Seq[A])(implicit num: Numeric[A]): Option[A] = { import num._ if (xs.isEmpty) None else Some(xs.sum / xs.size) }
编译错误信息:
cmd11.sc:4: value / is not a member of type parameter A else Some(xs.sum / xs.size) ^Compilation Failed
错误原因
代码存在两个核心问题:
- 类型不匹配:
xs.sum的类型是泛型参数A,但xs.size返回值是Int类型,即使A是数值类型,也没有定义A和Int之间的除法运算规则。 - 类型类约束不足:Scala标准库的
Numeric[A]是最通用的数值类型抽象,只定义了加、减、乘、类型转换等基础操作,没有提供通用除法方法div——因为整数类型的除法存在截断取整、精度损失的问题,不属于所有数值类型的通用能力,因此除法被定义在Numeric的两个子类中:Fractional[A]:对应Float、Double、BigDecimal这类支持分数除法的类型,提供标准除法运算Integral[A]:对应Int、Long这类整数类型,提供取商、取余运算
修正实现
根据业务需求可以选择两种实现方式:
- 如果需要输入输出类型保持一致,仅支持分数类型计算均值,使用
Fractional[A]作为隐式约束,同时通过fromInt方法将序列长度转换为A类型:
def mean[A](xs: Seq[A])(implicit num: Fractional[A]): Option[A] = { import num._ if (xs.isEmpty) None else Some(xs.sum / fromInt(xs.size)) }
- 如果需要兼容所有数值类型(包括整数),避免整数除法的精度问题,直接返回Double类型的均值结果即可:
def mean[A](xs: Seq[A])(implicit num: Numeric[A]): Option[Double] = { if (xs.isEmpty) None else Some(num.toDouble(xs.sum) / xs.size) }
内容的提问来源于stack exchange,提问作者Sergey Bushmanov
相关产品推荐
相关产品推荐

