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

时间:2015-08-05 07:37:56

标签: scala

  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(_) == '-')
  }

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

2 个答案:

答案 0 :(得分:2)

此scala代码:

object O {
  val i = 1

  def foo = {
    i
  }

  def bar = {
    val x = 1
    x
  }
}

编译到这个java:

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

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

检查我的scala-to-java工具,有助于了解scala在这种情况下的工作原理。

答案 1 :(得分:0)

您可以轻松测试这一点,为您的长度计算添加睡眠

  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(_) == '-')
  }

是的,对象会更快,但我不认为在你的情况下这种差异很重要。 你最好将所有常量保留在对象中(魔术数字/字符串总是坏主意),而使用对象进行计算并不是一个干净的解决方案。