【问题标题】:how to write a generic function in scala?如何在scala中编写通用函数?
【发布时间】:2020-05-14 06:48:52
【问题描述】:

我想计算数组 a 中每两个连续元素的平均值,并返回一个新数组。参数类型 T 可以是任何数值类型,例如 Byte、Short、Int、Float 和 Double。我不知道如何使它工作。提前致谢!

def center[T](a: Array[T]): Array[T] = {
  for (i <- 0 until a.size - 1) yield (a(i) + a(i + 1)) / 2
}

【问题讨论】:

  • 检查逆变和协方差:docs.scala-lang.org/tour/variances.html
  • 这里更多的是关于类型约束,例如。 [T: Numeric]
  • @Sid Variance 适用于类而不是方法,因此与此无关。

标签: scala generics


【解决方案1】:

我们必须处理的一个问题是整数除法产生整数结果:(2+3)/2 == 2

如果我们决定我们总是想要分数结果(可能是Double?),那么它会稍微简化一下任务。剩下的就是如何处理任意数字类型的输入了。

def center[N](a:Array[N])(implicit ev:Numeric[N]):Array[Double] = {
  import ev._
  if (a.lengthIs < 2) a.map(_.toDouble)
  else a.sliding(2)
        .map{case Array(a,b) => (a+b).toDouble/2.0}.toArray
}

测试:

center(Array(2, 3, 11, 4, 71))
//res0: Array[Double] = Array(2.5, 7.0, 7.5, 37.5)

center(Array(2.3, 1.1, 4.5, 7.1))
//res1: Array[Double] = Array(1.7, 2.8, 5.8)

【讨论】:

  • 感谢 jwvh,这几乎解决了我的问题。我知道返回 Array[T] 是技巧。
  • 返回类型 Array[T] 很困难如果 A)您希望 T 处理小数和整数, B)除法是必须的。积分除法与分数除法不同。有关该主题的更多详细信息,请参阅this rather old question
【解决方案2】:

这个代码示例没有分割,因为你应该定义你自己的类型类来按整数值进行潜水。

def center[T: Numeric](a: Array[T]): Array[T] = {
  a.sliding(2).map { case Array(f, s) => Numeric[T].plus(f, s) }.toArray
}

【讨论】:

    猜你喜欢
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 2023-01-21
    • 1970-01-01
    相关资源
    最近更新 更多