在Scala中应用和lambdas

时间:2015-09-26 17:56:39

标签: scala lambda apply

我有以下代码

scala> val builder = new StringBuilder("foo bar baz ")
builder: StringBuilder = foo bar baz

scala> (0 until 5) foreach { builder.append("!") }

scala> builder.toString
res15: String = foo bar baz !

我想这实际上就像

(0 until 5) foreach builder.append("!").apply

发生。任何人都可以向我解释为什么会发生这种情况或者我错了究竟发生了什么?

2 个答案:

答案 0 :(得分:7)

要了解发生了什么,我使用了我的小工具scala-to-java

您的代码转换为Java,如下所示:

public final class _$$anon$1 {
  private final StringBuilder builder = new StringBuilder("foo bar baz ");

  private StringBuilder builder() {
    return this.builder;
  }

  {
    RichInt$.MODULE$.until$extension0(Predef$.MODULE$.intWrapper(0), 5).foreach((Function1<Object, Object>)this.builder().append("!"));
    this.builder().toString();
  }
}

正如您所看到的,builder.append("!")的结果(也是StringBuilder)只是强制转换为Function1并在foreach中用作函数参数。

显然,StringBuilder确实是一个函数,如果你检查它的类型层次结构:

  • StringBuilder(scala.collection.mutable)
  • AbstractSeq(scala.collection.mutable)
  • AbstractSeq(scala.collection)
  • Seq(scala.collection)
  • PartialFunction(scala)
  • 功能1(scala)

作为结论:

  • 您可以将任何StringBuilder用作IntChar
  • 中的函数或部分函数
  • 在您的情况下,append仅评估一次,结果(StringBuilder)用作函数。

答案 1 :(得分:2)

Int => Unit期望您提供() => StringBuilder的{​​{1}}函数(在您的情况下)StringBuilder。但是,由于(0 until 5) foreach { _ => builder.append("!")} 是一个集合,因此选择“应用”函数来检索特定索引处的字符作为要在foreach循环中应用的函数。

您可以使用以下方法修复代码:

<code>
if(abc == "google")
</code>