坚持创建隐式可转换/从Int Natgural数字类

时间:2017-05-06 17:49:38

标签: scala implicit-conversion

几天前我开始玩Scala。 我想要做的是写一个非常小的类来表示自然数,我希望它可以从/ Int隐式转换。老实说,到目前为止我还没有做过很多。这是代码:

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之后它没有输出任何东西它没有正确退出。

我做错了什么?

1 个答案:

答案 0 :(得分:3)

implicit Natural => Int的定义是无限递归的原因;您编写的内容等同于以下内容(在代码中明确隐式转换):

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编译代码来获取此信息,该代码显示了代码的内部编译器表示(在所有代码已经解决之后):

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