如何在Scala中修补新的控制结构?

时间:2011-11-06 16:38:16

标签: scala

是否有可能在Scala中修补一个新的控制结构?基本上我想定义几个控制结构,比如下面的方法,除非是方法,并且可以在项目的任何地方访问它们。

def unless(condition: => Boolean)(body: => Unit):Unit = if(!condition) body

2 个答案:

答案 0 :(得分:11)

您不能猴子补丁,它会更改已存在的对象。但是,在大多数情况下,您可以编写一个隐式转换,其行为方式相同(并且可以说更安全)。

首先,编写unless时,您不需要它成为每个类的方法。只需将其粘贴在某个对象中即可导入。

object Utility {
  def unless(condition: => Boolean)(body: => Unit):Unit = if(!condition) body
}

import Utility._

但有时你希望它像一个类上的方法一样。例如,我经常写

option.map(x => f(x)).getOrElse(default)

可以更简洁地写成折叠:

option.fold(default)(x => f(x))

除了Option没有折叠。所以我:

class OptionWrapper[A](o: Option[A]) {
  def fold[Z](default: => Z)(action: A => Z) = o.map(action).getOrElse(default)
}
implicit def option_has_utility[A](o: Option[A]) = new OptionWrapper(o)

(这被称为“皮条客我的图书馆”模式)。现在我可以使用fold来获取内容,因为只要有一个选项并且我调用fold方法,编译器就会意识到没有fold方法并且可以查看它可以转换的任何方式将该类转换为具有fold的类。有这样一种方法,新类对现有选项完全按照类本身fold方法的要求进行。

答案 1 :(得分:2)

如果您的所有课程都在一个软件包中(请记住Scala中的软件包can be nested!),您可以将您的定义放在package object中。