jwv*_*wvh 6 scala type-parameter
我们知道,我们可以添加(减去/乘/等)两个不同Numeric
类型的数字,结果将是两种类型中较宽的一种,无论它们的顺序如何.
33F + 9L // Float + Long == Float
33L + 9F // Long + Float == Float
Run Code Online (Sandbox Code Playgroud)
这是因为各7 Numeric
类(Byte
,Short
,Char
,Int
,Long
,Float
,Double
)具有7种不同的+()
方法(以及-()
,*()
等),一个用于每个Numeric
可接收为传递的参数的类型.[有一个额外的+()
方法来处理String
参数,但这里不需要关注我们.]
现在考虑以下内容:
implicit class PlusOrMinus[T: Numeric](a: T) {
import Numeric.Implicits._
def +-(b: T) = if (util.Random.nextBoolean) a+b else a-b
}
Run Code Online (Sandbox Code Playgroud)
如果两个操作数是相同类型,则它可以工作,但如果第一个操作数的类型比第二个操作数的类型宽,它也可以工作.
11F +- 2L // result: Float = 9.0 or 13.0
Run Code Online (Sandbox Code Playgroud)
我相信这里发生的是编译器使用弱一致性来实现第二个操作数(参数)上的数字扩展,b
因为它传递给+-()
方法.
但第一个操作数不会扩大以匹配第二个.它甚至不会编译.
11L +- 2F // Error: type mismatch; found: Float(2.0) required: Long
Run Code Online (Sandbox Code Playgroud)
这种限制有什么办法吗?
我不能为b
参数(def +-[U: Numeric](b: U) = ...
)使用不同的类型参数,因为Numeric
通过类型参数表示的a只能添加/减去它自己的类型.
是创建7个不同的类别(唯一的解决办法PlusOrMinusShort/Int/Long/
有7种不同的方法(等)def +-(b:Short)
,def +-(b:Int)
,def +-(b: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
}
Run Code Online (Sandbox Code Playgroud)
然后,我得到以下交互:
scala> 11F +- 2L
res0: Float = 9.0
scala> 11L +- 2F
res1: Float = 9.0
Run Code Online (Sandbox Code Playgroud)
这个想法是,如果我可以有一个 function plusOrMinus
,那么整个问题就会变得微不足道,因为任何一个参数都可能发生相同的扩展。定义了这样一个函数后,问题就变成了如何将其嵌入到隐式类中以中缀形式使用它。
在这里,我们只有两种情况:要么需要扩展第二个参数,要么需要扩展隐式类包装的参数。第一种情况由第一种+-
方法涵盖(出于您在上面观察到的原因)。然而,对于第二个,我们需要明确地说存在一些可能的转换,并将转换的泛型类型传递给plusOrMinus
.
归档时间: |
|
查看次数: |
439 次 |
最近记录: |