ope*_*sas 10 generics scala implicit-conversion
我认为通过一个简单的例子来解释它更容易.(欢迎帮助改写标题;-)
我想实现一个squared方法,并使用implicit def,自动将其添加到任何支持*-operator的类.
使用Int非常容易:
class EnhancedInt(x: Int) { def squared = x * x }
implicit def IntToEnchancedInt(x: Int) = new EnhancedInt(x)
Run Code Online (Sandbox Code Playgroud)
但是对于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 }
Run Code Online (Sandbox Code Playgroud)
我想知道如何将它应用于任何数字类,或者甚至更好地应用于任何支持*-operator的类.
如果没有*为要处理的每种类型编写样板转换,那么使用方法的任何类型的解决方案都是不可能的.基本上要做到这一点,你需要一个递归结构类型,而Scala不支持那些因为JVM类型擦除.有关详细信息,请参阅此帖子.
你可以得到相当接近你想要使用类型类与沿什么Numeric类型的类,(由回答启发这个和这个问题).这适用于大多数原语:
//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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
812 次 |
| 最近记录: |