在 Scala 中应用和 lambda
Apply and lambdas in Scala
我有如下一段代码
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
发生了。谁能向我解释为什么会这样,或者如果我错了到底发生了什么?
foreach
需要一个函数(在您的情况下)Int => Unit
您提供 () => StringBuilder
。但是,由于 StringBuilder
是一个集合,因此选择 'apply' 函数来检索特定索引处的字符作为要在 foreach 循环中应用的函数。
您可以通过以下方式修复您的代码:
(0 until 5) foreach { _ => builder.append("!")}
为了了解发生了什么,我使用了我的小工具 scala-to-java。
您的代码转换为 Java 如下所示:
public final class _$$anon {
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
确实是一个函数,如果您检查它的类型层次结构:
- 字符串生成器 (scala.collection.mutable)
- 抽象序列 (scala.collection.mutable)
- 抽象序列 (scala.collection)
- 顺序 (scala.collection)
- 偏函数 (scala)
- 函数 1 (scala)
作为结论:
- 您可以使用任何
StringBuilder
作为函数或从 Int
到 Char
的部分函数
- 在你的例子中,
append
只计算一次,它的结果 (StringBuilder
) 被用作一个函数。
我有如下一段代码
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
发生了。谁能向我解释为什么会这样,或者如果我错了到底发生了什么?
foreach
需要一个函数(在您的情况下)Int => Unit
您提供 () => StringBuilder
。但是,由于 StringBuilder
是一个集合,因此选择 'apply' 函数来检索特定索引处的字符作为要在 foreach 循环中应用的函数。
您可以通过以下方式修复您的代码:
(0 until 5) foreach { _ => builder.append("!")}
为了了解发生了什么,我使用了我的小工具 scala-to-java。
您的代码转换为 Java 如下所示:
public final class _$$anon {
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
确实是一个函数,如果您检查它的类型层次结构:
- 字符串生成器 (scala.collection.mutable)
- 抽象序列 (scala.collection.mutable)
- 抽象序列 (scala.collection)
- 顺序 (scala.collection)
- 偏函数 (scala)
- 函数 1 (scala)
作为结论:
- 您可以使用任何
StringBuilder
作为函数或从Int
到Char
的部分函数
- 在你的例子中,
append
只计算一次,它的结果 (StringBuilder
) 被用作一个函数。