`def` vs `val` vs `lazy val` evaluation in Scala

前端 未结 8 952
再見小時候
再見小時候 2020-11-30 19:05

Am I right understanding that

  • def is evaluated every time it gets accessed

  • lazy val is evaluated once it gets acce

相关标签:
8条回答
  • 2020-11-30 20:08

    I would like to explain the differences through the example that i executed in REPL.I believe this simple example is easier to grasp and explains the conceptual differences.

    Here,I am creating a val result1, a lazy val result2 and a def result3 each of which has a type String.

    A). val

    scala> val result1 = {println("hello val"); "returns val"}
    hello val
    result1: String = returns val
    

    Here, println is executed because the value of result1 has been computed here. So, now result1 will always refer to its value i.e "returns val".

    scala> result1
    res0: String = returns val
    

    So, now, you can see that result1 now refers to its value. Note that, the println statement is not executed here because the value for result1 has already been computed when it was executed for the first time. So, now onwards, result1 will always return the same value and println statement will never be executed again because the computation for getting the value of result1 has already been performed.

    B). lazy val

    scala> lazy val result2 = {println("hello lazy val"); "returns lazy val"}
    result2: String = <lazy>
    

    As we can see here, the println statement is not executed here and neither the value has been computed. This is the nature of lazyness.

    Now, when i refer to the result2 for the first time, println statement will be executed and value will be computed and assigned.

    scala> result2
    hello lazy val
    res1: String = returns lazy val
    

    Now, when i refer to result2 again, this time around, we will only see the value it holds and the println statement wont be executed. From now on, result2 will simply behave like a val and return its cached value all the time.

    scala> result2
    res2: String = returns lazy val
    

    C). def

    In case of def, the result will have to be computed everytime result3 is called. This is also the main reason that we define methods as def in scala because methods has to compute and return a value everytime it is called inside the program.

    scala> def result3 = {println("hello def"); "returns def"}
    result3: String
    
    scala> result3
    hello def
    res3: String = returns def
    
    scala> result3
    hello def
    res4: String = returns def
    
    0 讨论(0)
  • 2020-11-30 20:09

    Yes, though for the 3rd one I would say "when that statement is executed", because, for example:

    def foo() {
        new {
            val a: Any = sys.error("b is " + b)
            val b: Any = sys.error("a is " + a)
        }
    }
    

    This gives "b is null". b is never evaluated and its error is never thrown. But it is in scope as soon as control enters the block.

    0 讨论(0)
提交回复
热议问题