Scala 函数中的值是否每次都生成?

Scala 函数中的值是否每次都生成?,scala,Scala,对象和函数IsValidUID是否做了完全相同的事情, 或者对象会更快,因为函数每次都计算len和DashIndex?您可以轻松测试这一点,将睡眠添加到长度计算中 object isValidUuid { val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75" val len = sample.length val dashIndices = sample.indices.filter(sample(_) == '-')

对象和函数IsValidUID是否做了完全相同的事情,
或者对象会更快,因为函数每次都计算len和DashIndex?

您可以轻松测试这一点,将睡眠添加到长度计算中

  object isValidUuid {
    val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
    val len = sample.length
    val dashIndices = sample.indices.filter(sample(_) == '-')

    def apply(string: String) = {
      string.length == len && dashIndices.forall(string(_) == '-')
    }
  }

  def isValidUuid(string: String) = {
    //f40473b8-9924-2a9a-bd82-7432191f2a75
    val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
    val len = sample.length
    val dashIndices = sample.indices.filter(sample(_) == '-')
    string.length == len && dashIndices.forall(string(_) == '-')
  }
是的,物体会更快,但我认为在你们的情况下,这种差异并不重要。 您最好将所有常量保留在object中(幻数/字符串总是不好的主意),而使用object进行计算并不是一个干净的解决方案。

此scala代码:

  object isValidUuidObj {
    val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
    val len = {
      Thread.sleep(1000)
      sample.length
    }
    val dashIndices = sample.indices.filter(sample(_) == '-')

    def apply(string: String) = {
      string.length == len && dashIndices.forall(string(_) == '-')
    }
  }

  def isValidUuid(string: String) = {
    //f40473b8-9924-2a9a-bd82-7432191f2a75
    val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
    val len = {
      Thread.sleep(1000)
      sample.length
    }
    val dashIndices = sample.indices.filter(sample(_) == '-')
    string.length == len && dashIndices.forall(string(_) == '-')
  }
编译到此java:

object O {
  val i = 1

  def foo = {
    i
  }

  def bar = {
    val x = 1
    x
  }
}
如您所见,函数中的所有值都被转换为局部变量,而对象中的值是类字段,它们只初始化一次(当对象初始化时)。为了清楚起见,我省略了对象初始化代码


检查我的工具,它有助于理解scala在这种情况下的工作方式。

函数版本可以在编译时优化为对象版本。我更想知道的是,如果这种优化目前在scala编译器中实现,或者这种优化在某些情况下不可能实现reason@Renkai这样的优化是不可能的,,否则,scala编译器必须知道变量初始化代码的所有可能的副作用。举个简单的例子,当您有
val i=getUUID()
时,scala编译器如何知道
getUUID()
是否有副作用,以及每次不调用此函数是否安全。常量可能可以优化,但我怀疑它是否实现了。不同版本的scala可能会给出结果,您使用的scalac版本是什么?@Renkai正确,但不适用于这种特殊情况。这是用ScalacV2.11.4编译的。
public class _$$anon$1$O$ {
  private final int i;

  public int i() {
    return this.i;
  }

  public int foo() {
    return this.i();
  }

  public int bar() {
    final int x = 1;
    return x;
  }

  {
    this.i = 1;
  }
}
// lazy object initialization omitted