Clojure 提供了一个名为 doto
的宏它接受它的参数和一个函数列表,并基本上调用每个函数,在(评估的)参数之前:
(doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2))
-> {a=1, b=2}
有没有办法在 Scala 中实现类似的东西?我设想具有以下形式的东西:
val something =
doto(Something.getInstance) {
x()
y()
z()
}
这将相当于
val something = Something.getInstance
something.x()
something.y()
something.z()
是否可以使用
scala.util.DynamicVariable
?请注意,对于工厂方法,例如
Something.getInstance
, 不可能使用通用的 Scala 模式val something =
new Something {
x()
y()
z()
}
最佳答案
我认为库中没有内置这样的东西,但您可以很容易地模仿它:
def doto[A](target: A)(calls: (A => A)*) =
calls.foldLeft(target) {case (res, f) => f(res)}
用法:
scala> doto(Map.empty[String, Int])(_ + ("a" -> 1), _ + ("b" ->2))
res0: Map[String,Int] = Map(a -> 1, b -> 2)
scala> doto(Map.empty[String, Int])(List(_ + ("a" -> 1), _ - "a", _ + ("b" -> 2)))
res10: Map[String,Int] = Map(b -> 2)
当然,只要您的函数返回正确的类型,它就可以工作。在您的情况下,如果该函数只有副作用(不是那么“scalaish”),您可以更改
doto
并使用 foreach
而不是 foldLeft
:def doto[A](target: A)(calls: (A => Unit)*) =
calls foreach {_(target)}
用法:
scala> import collection.mutable.{Map => M}
import collection.mutable.{Map=>M}
scala> val x = M.empty[String, Int]
x: scala.collection.mutable.Map[String,Int] = Map()
scala> doto(x)(_ += ("a" -> 1), _ += ("a" -> 2))
scala> x
res16: scala.collection.mutable.Map[String,Int] = Map(a -> 2)
关于scala - `doto` 用于 Scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11118881/