Stuck创建可隐式转换from /到Int Natgural数字类

问题描述:

我几天前开始玩Scala。 我想要做的是编写一个非常小的代表自然数的类,我希望它可以隐式地转换成Int。老实说,到目前为止我还没有做很多。下面是代码:Stuck创建可隐式转换from /到Int Natgural数字类

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它不会输出任何数据,它不会正常退出。

我在做什么错?

您对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 

我的编译代码得到这个信息与​​,这显示你的代码的内部编译器表示之后它已经typechecked(和所有implicits已经解决):

$ 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'''真的很有帮助,我不知道这件事。你能解释为什么你不建议使用隐式转换吗?因为它们是混淆的来源或者还有其他原因?我真的有一个印象,它在scala中很常见。 – Gonzalez

+1

作为一个初学者,你作为一个初学者被隐藏的转换所困惑,你花时间继续研究这个问题,并问这个问题,IMO是一个相当好的指标,隐含的转换是混淆的一个重要来源。关于这个问题有很多话要说,请打开另一个问题“为什么我不应该在代码中使用隐式转换?” :) – OlivierBlanvillain