类型参数和数字扩展

时间:2016-09-01 16:55:21

标签: scala type-parameter

我们知道,我们可以添加(减去/乘/等)两个不同Numeric类型的数字,结果将是两种类型中较宽的一种,无论它们的顺序如何。

33F + 9L  // Float + Long == Float
33L + 9F  // Long + Float == Float

这是因为7个Numeric类中的每一个(ByteShortCharIntLong,{{1 },Float)有7种不同的Double方法(以及+()-()等),每种*()类型一种,可以作为传递参数。 [还有Numeric方法用于处理+()参数,但这里不需要关注我们。]

现在考虑以下事项:

String

如果两个操作数是相同的类型,则它可以工作,但如果第一个操作数的类型比第二个操作数的类型宽,它也可以工作。

implicit class PlusOrMinus[T: Numeric](a: T) {
  import Numeric.Implicits._
  def +-(b: T) = if (util.Random.nextBoolean) a+b else a-b
}

我相信这里发生的事情是编译器使用weak conformance在第二个操作数(11F +- 2L // result: Float = 9.0 or 13.0 参数)上实现numeric widening,因为它传递给{{ 1}}方法。

但是第一个操作数不会被扩大以匹配第二个。它甚至无法编译。

b

有没有办法绕过这种限制?

我无法为+-()参数(11L +- 2F // Error: type mismatch; found: Float(2.0) required: Long )使用不同的类型参数,因为通过类型参数表示的b只能加/减它&# 39;自己的类型。

是使用7种不同方法(def +-[U: Numeric](b: U) = ...NumericPlusOrMinusShort/Int/Long/等创建7个不同类(def +-(b:Short)等)的唯一解决方案吗?

1 个答案:

答案 0 :(得分:4)

这是一种方式:

Api.addRoute('/charge'

然后,通过这个,我得到以下互动:

implicit class PlusOrMinus[T: Numeric](a: T) {
  import Numeric.Implicits._
  def +-(b: T) = plusOrMinus(a,b)
  def +-[U: Numeric](b: U)(implicit ev: T => U) = plusOrMinus[U](a,b)

  private def plusOrMinus[W: Numeric](a: W, b: W): W =
    if (util.Random.nextBoolean) a+b else a-b
}

我的想法是,如果我只能拥有一个函数scala> 11F +- 2L res0: Float = 9.0 scala> 11L +- 2F res1: Float = 9.0 ,那么整个问题就会变得微不足道,因为任何一个参数都会发生同样的扩大。在定义了这样一个函数之后,问题变成了如何将它嵌入到隐式类中以便以中缀形式使用它。

这里,我们只有两种情况:第二个参数需要加宽,或隐式类包装的参数需要加宽。第一个plusOrMinus方法涵盖了第一个案例(由于您在上面观察到的原因)。但是,对于第二种情况,我们需要明确说明存在一些可能的转换,并将转换的泛型类型传递给+-