概括了scala中的隐式函数

时间:2017-08-04 16:41:14

标签: scala implicit

我是Scala的新手,在使用隐式函数时遇到了一些麻烦。

假设我有一个隐式函数,将Strings转换为Option[String],写成

implicit def stringToOption(s: String): Option[String] = if(s.isEmpty) { None } else { Some(s) }

然后我有一个XML树,它可能有也可能没有属性<thing>

我还有2个类使用这个隐式函数,如:

case class ClassA(field: Option[String])

object ClassA {

    implicit val decoder(nodeSeq: NodeSeq) =>
      ClassA(field = nodeSeq \@ "thing")
}

case class ClassB(field: Option[String])

object ClassB {

    implicit val decoder(nodeSeq: NodeSeq) =>
      ClassB(field = nodeSeq \@ "thing")
}

有没有办法存储隐式函数,以便这两个单独的类都知道将String转换为Option[String]

通常情况下,我会将stringToOption放入其中一个类中:

case class ClassB(field: Option[String])

object ClassB {

    implicit def stringToOption(s: String): Option[String] = if(s.isempty) {None} else {Some(s)}

    implicit val decoder(nodeSeq: NodeSeq) =>
      ClassB(field = nodeSeq \@ "thing")
}

但是,我想把它粘贴在其他地方,以便它可用于两个类,我不需要在两者中重写它。这可能吗?

提前致谢。

1 个答案:

答案 0 :(得分:2)

隐式函数被认为是一种不好的做法,因为它们使代码更难以遵循并使错误更容易。他们目前需要在没有警告的情况下使用语言导入there is discussion to potentially heavily restrict them

那就是说,你可以做你所要求的。 在某个对象中定义隐式函数,然后将其导入到您需要的位置。

object DangerousImplicits {
  implicit def stringToOption(s: String): Option[String] = if(s.isempty) {None} else {Some(s)}
}

现在您可以将其导入到您希望进行此隐式转换的任何位置。 (我建议在方法中导入以最小化导入范围)

import DangerousImplicits.stringToOption