多态方法

时间:2016-11-06 18:11:00

标签: scala polymorphism

在使用Java一段时间后,我对Scala相当新,所以如果这是一个基本问题我会道歉。我有一个方法,我想以浮点数或双精度运行,似乎用Scala的多态性相当容易。在Java中,我发现这样做的唯一方法是重载方法并使用一个浮点数参数而另一个采用双参数,但我希望多态可以让我避免这种情况并且只有一个方法可以将与之合作。到目前为止我实现它的方式看起来像这样(https://stackoverflow.com/a/4033390/6247850如何使泛型操作在参数之间工作):

def Sample[A: Numeric](x: A, y: A)(implicit num: Numeric[A]): A= {
  import num._
  var out = 2.0.asInstanceOf[A] * x * y
  return out
}

这适用于双精度,但如果我尝试在Float中运行它会导致ClassCastException。我可以通过将其更改为2.0.toFloat.asInstanceOf[A]来硬编码解决方法,这让我觉得必须有一些方法可以做到这一点,但是像这样的硬编码会使得它变得通用。我还必须做一些看起来不成比例的工作,通过使用这个答案https://stackoverflow.com/a/34977463/6247850来使分工正常工作,然后建立它以便比工作更少的比较。

基本上,我想要的是能够指定方法应该运行并返回的精度。问题来自于将方法中使用的其他变量转换为适当的类型,因为.asInstanceOf[A]除非已经是正确的类型,否则不起作用。

1 个答案:

答案 0 :(得分:3)

这是一个使用Numeric明确方法的简短解决方案:

def Sample[A: Numeric](x: A, y: A)(implicit num: Numeric[A]): A = {
  num.times(
    num.fromInt(2),
    num.times(x, y)
  )
}

这允许首先解决重载算术运算符的任何歧义。这里的实际关键是使用fromInt方法,因此我们可以再次使用运算符将​​其写得更短(就像在代码中一样):

def Sample[A: Numeric](x: A, y: A)(implicit num: Numeric[A]): A = {
  import num._
  fromInt(2) * x * y
}

你不需要任何演员(在这个特定的例子中)。这是一个用法演示:

scala> Sample(2.5D, 0.01D)
res12: Double = 0.05

scala> Sample(2.5F, 0.01F)
res13: Float = 0.049999997

关于更一般的情况,如果只有一些数字而不是2并且您不知道您希望提前使用哪种类型,我认为,您无法解决问题一个多态函数。您可以定义一个类型类,并为您希望它使用的特定类型提供隐式实例(ad-hoc polymorphism)。