加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 类型参数和数字扩展

发布时间:2020-12-16 18:51:12 所属栏目:安全 来源:网络整理
导读:我们知道,我们可以添加(减去/乘/等)两个不同数字类型的数字,结果将是两种类型中较宽的一种,无论它们的顺序如何. 33F + 9L // Float + Long == Float33L + 9F // Long + Float == Float 这是因为7个数字类(Byte,Short,Char,Int,Long,Float,Double)中的每一个
我们知道,我们可以添加(减去/乘/等)两个不同数字类型的数字,结果将是两种类型中较宽的一种,无论它们的顺序如何.

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

这是因为7个数字类(Byte,Short,Char,Int,Long,Float,Double)中的每一个都有7个不同的()方法(和 – (),*()等),每个数字类型都有一个作为传递参数接收. [有一个处理String参数的extra()方法,但这里不需要关注我们.]

现在考虑以下内容:

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

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

11F +- 2L  // result: Float = 9.0 or 13.0

我相信这里发生的是编译器使用weak conformance在第二个操作数(b参数)上实现numeric widening,因为它被传递给 – ()方法.

但第一个操作数不会扩大以匹配第二个.它甚至不会编译.

11L +- 2F  // Error: type mismatch; found: Float(2.0) required: Long

这种限制有什么办法吗?

我不能为b参数使用不同的类型参数(def – [U:Numeric](b:U)= …),因为通过类型参数表示的数字只能添加/减去它自己的类型.

是使用7种不同方法(def – (b:短),def – (b:Int),def – (b:Long)等创建7个不同类(PlusOrMinusShort / Int / Long /等)的唯一解决方案. )?

解决方法

这是一种方式:

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,那么整个问题就会变得微不足道,因为任何一个参数都可能发生相同的扩展.在定义了这样一个函数之后,问题变成了如何将它嵌入到一个隐式类中以便在中缀形式中使用它.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读