2017-05-06 8 views
1

私は数日前にScalaで演奏を始めました。 私がしたいのは、自然数を表す非常に小さなクラスを書くことです。暗黙のうちに/からIntに変換できるようにしたいと思います。正直なところ私はこれまでに多くのことをしていません。ここでは、コードは次のとおりです。暗黙のうちに変換ができない/からInt Natgural numbersクラス

object main { 
    class Natural(n: Int) { 
    def isDividerOf(m: Natural): Boolean = m % n == 0 
    } 

    implicit def Int(m: Natural): Int = m 
    implicit def Natural(n: Int): Natural = new Natural(n) 

    def main(args: Array[String]) ={ 
    println("test") 
    println(60 isDividerOf 600) 
    } 
} 

コードをコンパイルすることができますが、私はそれ(関係なく、私はisDividerOfの引数として使用する番号)を実行すると、プログラムの実行が一時停止している/印刷後言い換えれば、永遠にハングtest正常に終了しても何も出力されません。

私は間違っていますか?

答えて

3

implicit Natural => Intの定義は、無限再帰の原因です。あなたが書いたことは(あなたのコード内で暗黙の型変換をexpliciting)以下と等価です:

implicit def Int2Nat(m: Natural): Int = Int2Nat(m) 

あなたの代わりにしたいどのようなものです:

implicit def Int2Nat(m: Natural): Int = m.n // Also change n to a val 

私は​​を使用してコードをコンパイルすることによって、この情報を得、これそれが型検査されています(と、すべての暗黙が解決された)後、コードの内部コンパイラ表現を示しています

$ scalac -Xprint:typer so.scala 
[[syntax trees at end of      typer]] // s.scala 
package <empty> { 
    object main extends scala.AnyRef { 
    def <init>(): main.type = { 
     main.super.<init>(); 
    () 
    }; 
    class Natural extends scala.AnyRef { 
     <paramaccessor> private[this] val n: Int = _; 
     <stable> <accessor> <paramaccessor> def n: Int = Natural.this.n; 
     def <init>(n: Int): main.Natural = { 
     Natural.super.<init>(); 
     () 
     }; 
     def isDividerOf(m: main.Natural): Boolean = main.this.Int(m).%(Natural.this.n).==(0) 
    }; 
    implicit def Int(m: main.Natural): Int = main.this.Int(m); 
    implicit def Natural(n: Int): main.Natural = new main.this.Natural(n); 
    def main(args: Array[String]): Unit = { 
     scala.Predef.println("test"); 
     scala.Predef.println(main.this.Natural(60).isDividerOf(main.this.Natural(600))) 
    } 
    } 
} 

しかし、暗黙的な変換は使用しないでください。これまで彼らは悪魔です。
あなたはIntに拡張メソッドと同じ結果を得ることができます。

implicit class isDividerOfOp(i: Int) { 
    def isDividerOf(other: Int): Boolean = other % i == 0 
} 
+0

おかげ@OlivierBlanvillainを。 '' -Xprint:typer''ビットは本当に役に立ちました。私はそれについて知らなかったのです。暗黙の変換を使用することを提案しない理由を説明できますか?彼らは混乱の源泉なのか、何か他の理由がありますか?私は正直なところ、スカラーではとても一般的な印象を受けました。 – Gonzalez

+1

初心者の方が暗黙のうちにあなたが時間を割いてこの問題を尋ねる時点まで混乱してしまったという事実は、IMOは暗黙の変換が混乱の大きな原因であることを示す良い指標です。件名にはたくさんのことがありますが、別の質問を「私のコードで暗黙的な変換を使用しない理由は何ですか?」と開いてください。 :) – OlivierBlanvillain

関連する問題