理解Scala中的值調用和名調用以及惰性求值

package com.zhengkw.scala.day03Exc

/**
 * @ClassName:Call
 * @author: zhengkw
 * @description:
 * @date: 20/04/23下午 10:05
 * @version:1.0
 * @since: jdk 1.8 scala 2.11.8
 */
object Call {
  def main(args: Array[String]): Unit = {
    callbyname(foo)
    println("____________")
    callbyvalue(foo)

  }

  /**
   * @descrption: 名調用 
   * @param a
   * @return: int
   * @date: 20/04/23 下午 10:12
   * @author: zhengkw
   */
  def callbyname(a: => Int) = {
    a
    a
    a
  }

  /**
   * @descrption:值調用
   * @param a
   * @return: int
   * @date: 20/04/23 下午 10:12
   * @author: zhengkw
   */
  def callbyvalue(a: Int) = {
    a
    a
    a
  }

  def foo(): Int = {
    println("foo is called")
    1
  }
}

名調用 Vs無參函數

名調用傳遞的是代碼塊!即高級函數/高階函數(Higher order functions)的名調用,原理是參數爲一個代碼塊!
高階函數的參數是一個無參函數,那麼傳遞的是無參函數!

惰性求值

變量var和常量val中只有val有惰性求值!關鍵字lazy
舉個栗子

var a =10
lazy val b =20

在這裏插入圖片描述
當他們同寫到一個.scala文件中作爲object的成員變量時,當加載到該文件,a會被直接加載出來,而b不會! 舉個例子!

  def main(args: Array[String]): Unit = {
        
       lazy  val a = {
            println("a.....")
            10
        }
        println("main -------")
        println(a)//a..... \n 10
        println(a) //10
        println(a)
        println(a)
        println(a)
        
    }

當他們同寫到一個.scala文件中作爲object的成員變量時,當加載到該文件,a會被直接加載出來,而b不會!

object LazyDemo2 {
    val a = {
        println("a...")
        10
    }
    lazy val b = {
        println("b...")
        20
    }
    
    def c = {
        println("c...")
        30
    }
    
    
    
    def main(args: Array[String]): Unit = {
        // layz其實是介於 val和def之間的狀況
        println(a)
        println(a)
        println(b)
        println(b)
        println(c)
        println(c)
        println(c)
        
    }
}

a…
10
10
b…
20
20
c…
30
c…
30
c…
30
Process finished with exit code 0

上面的代碼中可以明顯的看到,a是在沒有調用時就已經開始了計算(這個最好打斷點看)!b是在調用以後才輸出b。。。,而C比較悲哀,必須調用一次計算一次!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章