我最近开始学习Scala隐含的“魔法”,并且我遇到了隐式Scala对象的麻烦。我已经尝试了所有可能的变种,但似乎没有任何效果。
让我们假设我有一个这样的类,有一些solve()
函数。如果输入a,b是Float,它应该返回2个Float值。否则它应返回另一个类型值:
class Solver[T](val a: T, val b: T) {
def solve[A](implicit num: customNumeric[T]): Option[(T, T)] = {
Option(
num.f(num.g(a)),
num.f(num.g(b)))
}
}
让我们假设另一个类型值是类的对象:
class MyClass[T] (x: T, y: T)(implicit num: customNumeric[T]) {
val field : T = num.f(x)
}
我们还假设我没有基本Scala数字中需要的函数,所以我应该创建自己的自定义数字。
以下是我所做的:
我使用我的方法f()和g()以及一些隐式对象为我自己的customNumeric创建了一个抽象类,这些对象扩展了我的customNumeric,用于某些值类型(例如Int,Float)和实现的方法:
abstract class customNumeric[T] {
def f(x: T): T
def g(x: T): T
}
object customNumeric {
implicit object IntIsCustomNumeric extends customNumeric[MyClass[Int]] {
def f(x: MyClass[Int]) = new MyClass[Int](x.field + 5)
def g(x: MyClass[Int]) = new MyClass[Int](x.field - 5)
}
implicit object FloatIsCustomNumeric extends customNumeric[Float] {
def f(x: Float): Float = x + 3
def g(x: Float): Float = x - 3
}
}
在我看来,Solver的solve()应该使用隐式的customNumeric对象来获取基于Solver输入值类型的solve()内引用的方法的实现。
但这不适用于编译器说:
could not find implicit value for parameter num: customNumeric[Int]
def f...
它也会因为构造函数MyClass
在同一行上没有足够的参数而抱怨。
我已经尝试制作伴侣对象以将Int
投射到MyClass
:
object Fraction {
implicit def int2MyClass(x: Int): MyClass[Int] = new MyClass[Int](x, 1)
}
但这似乎也不起作用。我试图创建另一个隐式对象来实现我在customNumeric [MyClass [Int]]中使用的方法。
你有什么想法吗?提前谢谢!
答案 0 :(得分:2)
问题在于您尝试使用本身需要相同隐式对象的类来定义隐式对象。
含义,这:
class MyClass[T] (x: T, y: T)(implicit num: CustomNumeric[T])
需要存在隐式CustomNumeric[T]
。您无法使用该类型定义IntIsCustomNumeric
:
implicit object IntIsCustomNumeric extends customNumeric[MyClass[Int]]
实施IntIsCustomNumeric
时,您需要为类型Int
实施,而不是类型MyClass[Int]
。当你这样做,即:
object CustomNumeric {
implicit object IntIsCustomNumeric extends CustomNumeric[Int] {
override def f(x: Int): Int = x
override def g(x: Int): Int = x
}
}
现在,您可以创建一个Solver[Int]
,它采用隐式CustomNumeric[Int]
:
def main(args: Array[String]): Unit = {
import CustomNumeric._
val solver = new Solver[Int](1, 2)
println(solver.solve)
}
现在,创建从Int
类型到创建MyClass[Int]
的内容的隐式转换也更容易:
implicit object MyClassIsCustomNumeric extends CustomNumeric[MyClass[Int]] {
override def f(x: MyClass[Int]): MyClass[Int] = new MyClass[Int](x.field + 5)
override def g(x: MyClass[Int]): MyClass[Int] = new MyClass[Int](x.field + 3)
}
implicit def intToMyClass(i: Int) = new MyClass[Int](i)
答案 1 :(得分:0)
您如何看待这个
object customNumeric {
implicit object IntIsCustomNumeric extends customNumeric[Int] {
def f(x: Int): Int = x + 3
def g(x: Int): Int = x - 3
}
implicit object FloatIsCustomNumeric extends customNumeric[Float] {
def f(x: Float): Float = x + 3
def g(x: Float): Float = x - 3
}
implicit def int2MyClass(x: Int): MyClass[Int] = new MyClass[Int](x, 1)
implicit object cn extends customNumeric[MyClass[Int]] {
def f(x: MyClass[Int]) = x.field + 5
def g(x: MyClass[Int]) = x.field - 5
}
}