当前位置:  开发笔记 > 编程语言 > 正文

如何用"_"定义的相同函数的执行与在Scala中使用命名变量定义的函数的执行方式不同

如何解决《如何用"_"定义的相同函数的执行与在Scala中使用命名变量定义的函数的执行方式不同》经验,为你挑选了1个好方法。

如何使用"_"定义的相同函数的执行与使用Scala中的命名变量定义的函数不同?

以下是两个函数定义的输出.

scala> import scala.util.Random
import scala.util.Random

scala> Seq("a", "b", "c").map(x => { val rand = new Random().nextInt;  x+":"+rand}).foreach(println)
a:1700883193
b:-1153799665
c:-784839760

scala> Seq("a", "b", "c").map({ val rand = new Random().nextInt;  _+":"+rand}).foreach(println)
a:-1775524209
b:-1775524209
c:-1775524209

它是否与部分定义的函数有关?我可能会遗漏一些东西.

似乎是重复的解释:我看到了类似的问题,但重点并不明确,并注意到不同点的答案.所以在这里问一下简单直接的例子.另一个问题的链接: 为什么在Scala中使用下划线时只定义一次值 希望它很清楚.



1> Yuval Itzcha..:

这不是因为部分功能,而是闭包的工作方式.当你写:

_ + ":" + rand

编译器互相配合:

(x: String) => x.+(":").+(rand)

这是一个Function1[String, String].编译器将lambda表达式扩展为具体AbstractFunction1捕获 rand.以下是生成的类的相关片段:

  private[this] val rand$1: Int = _;
  def (rand$1: Int): <$anon: Function1> = {
    anonfun$1.this.rand$1 = rand$1;
    anonfun$1.super.();
    ()

请注意,rand$1将其分配给this.rand$1生成的AbstractFunction1实例中的本地字段.此字段将在每次调用时重复使用map,这就是为什么每次迭代都没有看到新值,而只是第一次出现.您可以在字节代码中看到,该init方法仅在运行时调用一次main:

public void main(java.lang.String[]);
  Code:
     0: aload_0
     1: ldc           #16        // String he
     3: ldc           #18        // String hello
     5: new           #20        // class Chapter5/X$$anonfun$main$1
     8: dup
     9: invokespecial #21        // Method Chapter5/X$$anonfun$main$1."":()V  <--- Here.
    12: invokespecial #25        // Method f$1:(Ljava/lang/Object;Ljava/lang/Object;Lscala/Function1;)Ljava/lang/Object;
    15: pop
    16: return

遍历集合f$1main方法体在哪里,并调用apply序列中的每个元素.

相反,当您为集合中的每个值引入一个新变量时,如下所示:

map(x => { val rand = new Random().nextInt;  x+":"+rand})

我们看到rand不再捕获,通过绑定到每个调用的新变量apply:

@SerialVersionUID(value = 0) final  class anonfun$1 extends scala.runtime.AbstractFunction1 with Serializable {
    final def apply(x: String): String = {
      val rand: Int = new scala.util.Random().nextInt();
      x.+(":").+(scala.Int.box(rand))
    };

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有