坚持创建隐式可转换 from/to Int 自然数 class

Stuck creating implicitly convertable from/to Int Natgural numbers class

我几天前开始玩 Scala。 我想做的是写一个非常小的 class 来表示自然数,我希望它可以隐式转换 from/to 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 的参数)程序执行永远是 paused/hung,在其他情况下打印后的单词 test 它不输出任何内容,它是否正确退出。

我做错了什么?

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