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

Fil*_*eca 5 scala

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

def unless(condition: => Boolean)(body: => Unit):Unit = if(!condition) body
Run Code Online (Sandbox Code Playgroud)

Rex*_*err 11

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

首先,unless正如所写,你不需要它成为每个类的方法.只需将其粘贴在某个对象中即可导入.

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

import Utility._
Run Code Online (Sandbox Code Playgroud)

但有时你确实希望它像一个类的方法.例如,我经常写

option.map(x => f(x)).getOrElse(default)
Run Code Online (Sandbox Code Playgroud)

这可以更紧凑地写成折叠:

option.fold(default)(x => f(x))
Run Code Online (Sandbox Code Playgroud)

除了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)
Run Code Online (Sandbox Code Playgroud)

(这被称为"皮条客我的图书馆"模式).现在我可以使用fold来获取我的内容,因为任何时候都有一个选项并且我调用该fold方法,编译器意识到没有fold方法并且环顾四周它可以将类转换为具有的类fold.有这样一种方法,新类对现有选项完全按照你fold自己对类本身方法的要求.

  • @Dan Burton - 使用猴子修补,你可以混合使用一些方法,其中一些方法没有; 这会引发一些问题,你希望一个对象有一个方法,但它没有被修补(或者修补了错误的版本).使用隐式转换,您具有编译时类型安全性:保证类具有它们具有的方法,并且保证转换有效. (5认同)