是否为每个隐式类转换创建了新的类实例?

时间:2016-11-06 20:37:59

标签: scala implicit

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次。每个隐式类转换都有新的类实例化吗?如果是,为什么?如果不是,为什么“!!!”打印三次?

2 个答案:

答案 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)
}