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

标签 generics scala implicit-conversion

我认为用一个简单的例子更容易解释。 (欢迎帮助重新表述标题;-)

我想实现一个 squared 方法,并使用隐式 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 }

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

最佳答案

如果不为要处理的每种类型编写样板转换,就不可能拥有适用于任何类型的 * 方法的解决方案。本质上要做到这一点,你需要一个递归结构类型,而 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

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

相关文章:

c++ - C++ 中的嵌套隐式转换

generics - Kotlin中的Nothing或Any和有什么区别

java - 访问参数化类型的类名

java - `Iterable` 的接口(interface)转换

json - 使用 circe-optics 从 json 中检索空值

c++ - 隐式转换没有发生

generics - 如何将Rust函数类型中的特征放入数组类型中?

scala - 如何解决 akka 版本兼容性问题?

scala - 玩! 2 斯卡拉 : Adding an error to a form in the controller code proper

c# - Xamarin.Forms 绑定(bind) - 隐式类型转换是否在代码中完成,而不是在 XAML 中完成?