object test extends App {
implicit class f(i: Int) { println("!!!"); def f = 42 + i }
1.f
2.f
3.f
}
在.class文件中我们看到
public static test$f f(int);
Code:
0: getstatic #16 // Field test$.MODULE$:Ltest$;
3: iload_0
4: invokevirtual #42 // Method test$.f:(I)Ltest$f;
7: areturn
所以,看起来有一个静态方法,但这段代码打印“!!!”跑步时3次。每个隐式类转换都有新的类实例化吗?如果是,为什么?如果不是,为什么“!!!”打印三次?
答案 0 :(得分:5)
您可以通过将其设为value class
来避免实例化您的扩展程序类implicit class f(val i: Int) extends AnyVal { def f = 42 + i }
请注意,那么您无法将println
放入其中,但这里引用了上面链接的文档:
在运行时,此表达式3.toHexString被优化为等效于静态对象上的方法调用(RichInt $ .MODULE $ .extension $ toHexString(3)),而不是对新实例化的对象的方法调用。
答案 1 :(得分:1)
是 - 隐式类是创建类的简写,隐式def用于创建实例,例如在您的示例中:
object test extends App {
class f(i: Int) { println("!!!"); def f=42+i}
implicit def toF(i : int) = new f(i)
}