在Scala中是否存在用于Rails"返回"方法的模拟?

Col*_*lin 5 scala ruby-on-rails scala-2.8

在Rails中,可以使用:

returning Person.create do |p|
  p.first_name = "Collin"
  p.last_name = "VanDyck"
end
Run Code Online (Sandbox Code Playgroud)

避免必须这样做:

person = Person.create
person.first_name = "Collin"
person.last_name = "VanDyck"
person
Run Code Online (Sandbox Code Playgroud)

我认为前一种方式更清洁,重复性更低.我发现自己在Scala项目中创建了这个方法:

def returning[T](value: T)(fn: (T) => Unit) : T = {
  fn(value)
  value
}
Run Code Online (Sandbox Code Playgroud)

我知道由于对象倾向于不可变,它的实用性有限,但是例如使用Lift,在Mapper类上使用这种方法效果很好.

是否有Scala模拟用于"返回",我不知道?或者,在Scala中有类似的方法可以做到这一点吗?

Rex*_*err 6

你的方法看起来很好,虽然我通常通过添加副作用的方法来做到这一点,这可以包括改变内部状态(或者类似的东西println):

class SideEffector[A](a: A) {
  def effect(f: (A => Any)*) = { f.foreach(_(a)); a }
}
implicit def can_have_side_effects[A](a: A) = new SideEffector(a)

scala> Array(1,2,3).effect(_(2) = 5 , _(0) = -1)
res0: Array[Int] = Array(-1, 2, 5)
Run Code Online (Sandbox Code Playgroud)

编辑:以防万一在原始示例中这将如何有用:

Person.create.effect(
  _.first_name = "Collin",
  _.last_name = "VanDyck"
)
Run Code Online (Sandbox Code Playgroud)

编辑:将方法的名称更改为"效果".我不知道为什么我没有去,以前的方式-侧的效果,而不是为命名的效果.


Kev*_*ght 5

对于你已经写好的东西,真的无法提高.正如你非常正确地指出的那样,惯用的Scala倾向于支持不可变对象,所以这种东西的用途有限.

另外,作为一个单行,如果你需要的话,实现自己并不是那么痛苦!

def returning[T](value: T)(fn: T => Unit) : T = { fn(value); value }
Run Code Online (Sandbox Code Playgroud)