【问题标题】:Is it possible to reference the chained object in a method call chain?是否可以在方法调用链中引用链接对象?
【发布时间】:2017-02-04 23:11:37
【问题描述】:

我有一个构建器调用链,其中一个调用必须附加到默认值,例如

var x = new X()
  .setA(1)
  .setB(2)
x = x.setList(x.getList :+ "itemtoappend")

有没有办法内联 setList 调用? (X 是第三方库)

我希望有一个关键字,比如“链”,这样使用:

val x = new X()
  .setA(1)
  .setB(2)
  .setList(chain.getList :+ "itemtoappend")

假设我没有能力在 X 上编写 appendToList 方法,并且不想编写并隐式转换到具有 appendToList 的类 MyX。

【问题讨论】:

  • 我希望简化的实际用例包括向 Spark ML StopWordsRemover 添加一些新词,以及向 Spark DataFrame 添加新列作为现有列的函数。

标签: scala chaining method-chaining


【解决方案1】:

您似乎想在构建对象的同时访问该对象两次。

class X {
  def setA(a: Int): X = this
  def setB(b: Int): X = this
  def setList(ss: Seq[String]): X = this
  def getList = Seq("head")
}

val x: X = Option( new X().setA(1).setB(2)
                 ).map(z => z.setList(z.getList :+ "itemtoappend")).get

【讨论】:

  • 太好了,这确实内联了所有内容,因此 x 可以是不可变的。这段代码的意图对我来说并不是很明显。这是一种常见的模式吗?
  • 很高兴你喜欢它。 (也许您可以将其标记为已接受的答案?)不,我认为这不是常见的模式。我意识到传递给匿名函数的参数是正在构建的对象的中间表示。我使用Option().get 创建/丢弃提供map() 方法的包装器。
  • 我接受了,谢谢。我在等着看是否有任何其他建议,但没有得到。我正在使用它,稍微调整一下使用 Some 而不是 Option:Some(new X().setA(1).setB(2)).map(z => z.setList(z.getList :+ "itemtoappend")).get
  • 确实如此。 Option/Some,几乎是一样的。我喜欢使用Option,因为Option(null)None,而Some(null)Some(null)。在这种情况下可能不适用,但要记住一些事情。
【解决方案2】:

我认为标准方法是编写一个同时进行设置和获取的方法,并传递一个函数。你可以称之为

val x = new X()
  .setA(1)
  .setB(2)
  .list(_ :+ "itemtoappend")

【讨论】:

  • 谢谢。这肯定比我的 appendToList 想法更好,更通用,但我认为仍然需要我发明 MyX 并隐式转换?
  • 啊,对,我虽然你问的是如何实现X,而不是你想用给定的X 编写链。是的,您可以选择隐式转换为MyX,使用var x 写出来,或者向X 的作者提交功能请求。
猜你喜欢
  • 1970-01-01
  • 2020-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多