scala – 类型参数和数字扩展
我们知道,我们可以添加(减去/乘/等)两个不同数字类型的数字,结果将是两种类型中较宽的一种,无论它们的顺序如何.
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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- angularjs – 指令应该与Angular JS中的控制器通信吗?
- scala sbt test在多个项目上运行setup和cleanup命令
- bootstrap table列属性的设置
- angular – 如何在表单中使用带有自定义控件的ngModel?
- angularjs – socket.io手动将用户添加到房间(node.js)
- crystal-reports – 最适合AngularJS和Crystal Reports的报
- 无法找到类型为scala.reflect.ClassManifest [T]的证据参数
- 如何在vim中编辑多列文本
- 《数据结构》实验二 线性表的实验
- Angular CLI可以在新组件中自动包含moduleId吗?