Scala:是否可以指出实现某种方法的泛型类

时间:2012-01-14 22:51:00

标签: generics scala implicit-conversion

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

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

使用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 }

我想知道如何将它应用于任何数字类,或者更好地应用于支持* - 运算符的任何类。

3 个答案:

答案 0 :(得分:8)

如果没有为要处理的每种类型编写样板转换,则无法使用*方法使用任何类型的解决方案。基本上要做到这一点,你需要一个递归结构类型,而Scala不支持那些因为JVM类型擦除。有关详细信息,请参阅此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

答案 1 :(得分:0)

答案 2 :(得分:0)

想一想。乘法在不同对象上具有不同的属性。例如,整数乘法是关联的和可交换的,标量乘法不是可交换的。并乘以浮点数... 但是,当然,你可以拥有你想要的特性或者具有类似于类型类的“特征和隐式”结构。