几天前我开始玩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
之后它没有输出任何东西它没有正确退出。
我做错了什么?
答案 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
}