加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

有没有办法“丰富”Scala类而不将代码包装到另一个对象中?

发布时间:2020-12-16 09:20:20 所属栏目:安全 来源:网络整理
导读:在 Scala 2.9中添加自定义方法到库类(丰富或“皮条客”),我不得不写这样的东西: object StringPimper { implicit def pimpString(s: String) = new { def greet: String = "Hello " + s }} 正如Scala 2.10发布的那样,我已经看到它引入了隐式类定义,理论上,
在 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)
}

这不会保存你的工作(但运行速度更快).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读