Scala中implicit classes的性能问题与最佳实践咨询
访问控制需求实现
要让y()仅在当前文件可访问,直接给隐式类加private修饰符即可:
private implicit class Foo(x : Person) { def y() = { println("y") } }
加了private修饰的隐式类仅在当前源文件的作用域内可见,其他文件无法调用该扩展方法。
隐式类扩展方法的底层逻辑
你写的隐式类本质是Scala提供的语法糖,编译期会完成两个自动转换:
- 编译器自动为隐式类生成对应的隐式转换方法,你的代码编译后会新增如下逻辑:
implicit def Foo(x: Person): Foo = new Foo(x)
- 当你调用
Person("","").y()时,编译器发现Person类本身没有定义y()方法,就会在当前作用域搜索可用的隐式转换,找到上述转换方法后,会将原代码自动改写为:
new Foo(Person("", "")).y()
整个转换逻辑全部在编译期完成,运行期就是普通的对象实例化和方法调用流程,没有额外的运行时反射开销。
和继承实现方案的性能对比
- 普通隐式类实现:每次调用
y()都会创建一个临时的Foo类对象,如果在高频循环场景下大量调用该方法,会产生很多短生命周期的小对象,增加GC负担,性能弱于继承方案。 - 优化后的隐式类实现:你可以将隐式类定义为值类(继承
AnyVal):
private implicit class Foo(val x: Person) extends AnyVal { def y() = println("y") }
这种情况下编译器会直接把方法调用优化为静态方法调用,不会生成Foo类的实例对象,性能和继承实现方案几乎没有差异。
内容的提问来源于stack exchange,提问作者Helix112
相关产品推荐
相关产品推荐

