有没有办法“丰富”Scala类而不将代码包装到另一个对象中?
在
Scala 2.9中添加自定义方法到库类(丰富或“皮条客”),我不得不写这样的东西:
object StringPimper { implicit def pimpString(s: String) = new { def greet: String = "Hello " + s } } 正如Scala 2.10发布的那样,我已经看到它引入了隐式类定义,理论上,这意味着通过在隐式方法中消除匿名类的对象来简化上述任务.我以为这会让我写一下 implicit class PimpedString(s: String) { def greet: String = "Hello " + s } 这对我来说看起来更漂亮.但是,这样的定义会导致编译错误: `implicit' modifier cannot be used for top-level objects 这通过将代码重新包装在对象中来解决: object StringPimper { implicit class PimpedString(s: String) { def greet: String = "Hello " + s } } 不用说,这几乎中和了改善的感觉. 那么有没有办法把它写得更短?去除包装对象? 我实际上有一个MyApp.pimps包,其中所有的皮条客都去(我没有太多,我会使用一些单独的包,如果我有),我厌恶导入MyApp.pimps.StringPimper._而不是MyApp. pimps.PimpedString或MyApp.pimps._.当然,我可以将所有隐式类放在一个包装器对象中,但这将意味着将它们全部放在单个文件中,这将是相当长的 – 非常难看的解决方案. 解决方法
现在的标准术语是丰富的.我不知道为什么不是以前,因为使用它的库方法被命名为RichString而不是PimpedString.
无论如何,您不能将隐式类放在任何内容中,但为了使用implicits,您需要使用方法,而不能将方法置于无效之中.但你可以欺骗所有的皮条客. // This can go in one file trait ImplicitsStartingWithB { implicit class MyBoolean(val bool: Boolean) { def foo = !bool } implicit class MyByte(val byte: Byte) { def bar = byte*2 } } // This can go in another file trait ImplicitsStartingWithS { implicit class MyShort(val short: Short) { def baz = -short } implicit class MyString(val st: String) { def bippy = st.reverse } } // This is a third file,if you want! object AllImplicits extends ImplicitsStartingWithB with ImplicitsStartingWithS {} scala> import AllImplicits._ import AllImplicits._ scala> true.foo res0: Boolean = false 您也可以使用pimps包对象执行此操作 – 通常您将在名为pimps的目录中放置一个名为package.scala的文件,然后 package object pimps extends /* blah blah ... */ { /* more stuff here,if you need it */ } 值得注意的是,作为一项新功能,价值观具有相当多的限制.有些是不必要的,但如果您想避免分配一个新的MyBoolean类(JVM通常可以大大优化,但通常不会达到裸机方法调用的程度),那么您必须解决这些限制.在这种情况下, // In some file,doesn't really matter where class MyBoolean(val bool: Boolean) extends AnyVal { def foo = !bool } package object pimps { def implicit EnrichWithMyBoolean(b: Boolean) = new MyBoolean(b) } 这不会保存你的工作(但运行速度更快). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |