2016-09-24 46 views
3

我最近開始學習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) 
} 

而且,我們還假設我沒有我需要的功能基本的斯卡拉數字,所以我應該做我自己的自定義數字。

這裏是我做了什麼:

我做我自己的customNumeric一個抽象類,用我的方法F()和G()和幾個擴展我的customNumeric一些值類型的隱式對象(整型,浮點爲例),並在其中實現的方法:

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

在我看來求解的解決()應使用隱customNumeric對象來獲得)基於類型的求解器的輸入值的參考內解決(方法的實現。

但是,這並不如編譯器工作說:

could not find implicit value for parameter num: customNumeric[Int] 
     def f... 

還抱怨,因爲在同一行沒有足夠的參數的構造函數MyClass

我已經試圖使伴侶對象投IntMyClass

object Fraction { 
    implicit def int2MyClass(x: Int): MyClass[Int] = new MyClass[Int](x, 1) 
} 

但也doen't似乎工作。我試圖讓另一個隱式對象來實現我在customNumeric [MyClass [Int]]中使用的方法。

你有什麼想法嗎?提前致謝!

回答

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]類型。當你這樣做時,我。E:

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) 
+0

感謝您的詳細解答!我認爲我明白了'Solver'將使用'IntIsCustomNumeric'對象,然後通過'intToMyClass'強制轉換方法將它隱式轉換爲'MyClass'(它具有方法實現)。但是試圖調試這個強制轉換的執行讓我想到編譯器知道'IntIsCN'應該被轉換爲'MyClassIsCN',因爲'IntIsCN'具有完整的方法實現。所以它可以只使用'IntIsCN'的方法來執行所有的操作。還有一個問題 - 如果'f(x:Int)'不返回'Int' –

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 
    } 

} 
相關問題