我认为用一个简单的例子来解释它会更容易。 (欢迎改写标题;;)

我想实现一个squared方法,并使用implicit def将其自动添加到任何支持* -operator的类中。

使用Int,这非常简单:

class EnhancedInt(x: Int) { def squared = x * x }

implicit def IntToEnchancedInt(x: Int) = new EnhancedInt(x)

但是,使用Any或AnyVal时,出现以下错误:
scala> class EnhanceAny(x: AnyVal) { def squared = x * x }
<console>:7: error: value * is not a member of AnyVal
       class EnhanceAny(x: AnyVal) { def squared = x * x }

我想知道如何将其应用于任何数字类,甚至更好地应用于支持* -operator的任何类。

最佳答案

如果不为您要处理的每种类型编写样板转换,就不可能有一种适用于*方法的任何类型的解决方案。从本质上讲,您将需要递归结构类型,并且由于JVM类型擦除,Scala不支持这些结构类型。有关更多详细信息,请参见此post

使用类型类以及Numeric类型类,您可以非常接近所需的内容(受thisthis问题的答案启发)。这将适用于大多数原语:

//define the type class
trait Multipliable[X] { def *(x: X): X}

//define an implicit from A <% Numeric[A] -> Multipliable[Numeric[A]]
implicit def Numeric2Mult[A](a: A)(implicit num: Numeric[A]): Multipliable[A] = new Multipliable[A]{def *(b: A) = num.times(a, b)}

//now define your Enhanced class using the type class
class EnhancedMultipliable[T <% Multipliable[T]](x: T){ def squared = x * x}

//lastly define the conversion to the enhanced class
implicit def Mult2EnhancedMult[T <% Multipliable[T]](x: T) = new EnhancedMultipliable[T](x)

3.squared
//Int = 9

3.1415F.squared
//Float = 9.869022

123456789L.squared
//Long = 15241578750190521

关于generics - Scala:是否可以指示实现某种方法的泛型类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8866030/

10-10 11:58