我想使用类型类来设计转换接口,代码如下:
case class Kilograms(value: Double) case class Pounds(value: Double) trait Convert[T,U] { def convert(input: T): U } object Convert { def apply[T:Convert,U:Convert] = implicitly[Convert[T,U]] def covert[T,U](input: T)(implicit c: Convert[T,U]): U = c.convert(input) implicit object kilogramsToPounds extends Convert[Kilograms,Pounds] { override def convert(input: Kilograms): Pounds = Pounds(input.value * 2.20462) } implicit object poundsToKilograms extends Convert[Pounds,Kilograms] { override def convert(input: Pounds): Kilograms = Kilograms(input.value / 2.20462) } }
但编译错误:
Error: wrong number of type arguments for A$A95.this.Convert,should be 2 def apply[T:Convert,U]] Error: could not find implicit value for parameter e: A$A95.this.Convert[T,U] def apply[T:Convert,U]] Error: not enough arguments for method implicitly: (implicit e: A$A95.this.Convert[T,U])A$A95.this.Convert[T,U]. Unspecified value parameter e. def apply[T:Convert,U]]
如果我改变def apply [T:Convert,U:Convert] =隐式[Convert [T,U]]为def apply [T,U](隐式c:转换[T,U]):转换[T,U] = c,没有编译错误!
我想知道发生了什么事?
另外,我查找一些信息,上下文限制是用单一类型参数(?)限制的
如果我想实现多个类型参数类型类,我该怎么办?
解决方法
上下文绑定语法T:U仅适用于只有一个类型参数S(符合T)的类型U.
这是有效的,因为您手动声明了Convert [T,U]的隐式:
def covert[T,U]): U = c.convert(input)
以下内容无效,因为编译器分别对Convert [T]和Convert [U]的上下文边界进行去糖,这没有意义.
def apply[T:Convert,U]]
(尝试脱糖)
def apply[T,U](implicit ev1: Convert[T],ev2: Convert[U]) = ...
见SLS 7.4 – Context and View Bounds:
A type parameter
A
of a method or non-trait class may also have one or more context boundsA : T
. In this case the type parameter may be instantiated to any typeS
for which evidence exists at the instantiation point thatS
satisfies the boundT
. Such evidence consists of an implicit value with typeT[S]
.