0

我有一堆自动生成的 java 代码,我将在 scala 中调用它们。目前所有的对象都是用 void setter 生成的,而不是返回this,这使得当你需要设置一堆值时真的很烦人(我不会通过初始化所有东西来使用构造函数,因为有 50 个字段)。例如:

val o = new Obj()
o.setA("a")
o.setB("b")
o.setC("c")

如果我能做这样的事情真的很酷

val o = with(new Obj()) {
  _.setA("a")
  _.setB("b")
  _.setC("c")
}

我不能将 andThen 与 anon 函数一起使用,因为它们需要返回对象。我是坚持目前的做事方式还是有一些我不知道的魔法。

4

3 回答 3

5

当然,您可以使用tap(Kestrel 组合器),您现在必须自己定义:

implicit class Tapper[A](val a: A) extends AnyVal {
  def tap[B](f: A => B): A = { f(a); a }
  def taps[B](fs: A => B*): A = { fs.map(_(a)); a }
}

它是这样工作的:

scala> "salmon".taps(
     |       println,
     |       println
     |     )
salmon
salmon
res2: String = salmon

另请注意

val myFavoriteObject = {
  val x = new Obj
  x.setA("a")
}

将允许您使用一个短名称来完成所有设置,同时分配一个更有意义的名称以供长期使用。

于 2013-07-18T17:38:38.617 回答
1

您可以使用从/到允许链接的包装类的隐式转换器。

就像是:

case class ObjWrapper(o: Obj) {
  def setA(a: String) = { o.setA(a); this }
  def setB(b: String) = { o.setB(b); this }
  def setC(c: String) = { o.setC(c); this }
}
implicit def wrapped2Obj(ow: ObjWrapper): Obj = ow.o

ObjWrapper(myObj).setA("a").setB("b").setC("c")

实际上,您甚至不需要隐式转换器,因为已调用了这些方法myObj

于 2013-07-18T17:29:07.107 回答
1

看看Scalaxy/Beans。但是请注意,它使用的是宏,因此应将其视为实验性的。

于 2013-07-18T18:01:06.100 回答