복붙노트

[SCALA] 스칼라 값으로 호출 대 이름으로 전화, 설명 필요

SCALA

스칼라 값으로 호출 대 이름으로 전화, 설명 필요

내가 알고있는 것처럼, 스칼라 함수는 하나라고 할 수있다

예를 들어, 우리는 함수가 호출되는 방법을 알고, 다음과 같은 선언을 주어?

선언:

def  f (x:Int, y:Int) = x;

요구

f (1,2)
f (23+55,5)
f (12+3, 44*11)

규칙하시기 바랍니다은 무엇입니까?

해결법

  1. ==============================

    1.당신이 준 예는 통화로 값 사용하기 때문에 나는 차이를 보여 새로운, 간단한 예를 제공 할 것입니다.

    당신이 준 예는 통화로 값 사용하기 때문에 나는 차이를 보여 새로운, 간단한 예를 제공 할 것입니다.

    첫째, 우리가 부작용으로 함수가 있다고 가정하자. 이 기능은 뭔가를 출력 한 다음 int를 돌려줍니다.

    def something() = {
      println("calling something")
      1 // return value
    }
    

    (: Int 인 X)과 (전화 별 이름 스타일 다른 X 이제 우리는 하나가 통화 별 가치 스타일의 인수를 제외하고는 정확히 동일 지능의 인수를 사용할 두 개의 함수를 정의하려고 : => INT).

    def callByValue(x: Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    
    def callByName(x: => Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    

    우리가 우리의 옆을 초래 함수를 호출 할 때 지금 무슨 일이?

    scala> callByValue(something())
    calling something
    x1=1
    x2=1
    
    scala> callByName(something())
    calling something
    x1=1
    calling something
    x2=1
    

    그래서 당신은 통화 별 값 버전에서 그것을 볼 수 전달 된 함수 호출의 부작용 (뭔가 ()) 한 번만 발생했습니다. 그러나, 통화 별 이름 버전, 부작용은 두 번 일어났다.

    통화 별 값 함수는 함수를 호출하기 전에 전달 된 표현의 값을 계산하기 때문에, 따라서 같은 값이 때마다 액세스 할 수있다. 그러나 통화로 이름 기능은 전달 된 표현의 가치가 액세스 할 때마다 재 계산.

  2. ==============================

    2.여기에 마틴 오더 스키의 예입니다 :

    여기에 마틴 오더 스키의 예입니다 :

    def test (x:Int, y: Int)= x*x
    

    우리는 평가 방법을 검토 한 빨리 (낮은 단계) 이러한 조건에서 어떤 결정하려면 :

    test (2,3)
    

    값으로 호출 시험 (2,3) -> 2 * (2) -> (4) 이름으로 호출 시험 (2,3) -> 2 * (2) -> (4) 다음 결과는 동일한 단계 번호로 진행한다.

    test (3+4,8)
    

    값으로 호출 시험 (7,8) -> 7 * 7 -> 49 이름으로 호출 (3 + 4) (4 + 3) -> (7) (3 + 4) -> 7 * 7 -> 49 여기에 값이 빠른에 의해 호출합니다.

    test (7,2*4)
    

    값으로 호출 시험 (7,8) -> 7 * 7 -> 49 > 49-7 * 7 : 이름으로 전화 이름은 빠른에 의해 여기에 전화

    test (3+4, 2*4) 
    

    값으로 호출 시험 (7,2 * 4) -> 시험 (7, 8) -> 7 * 7 -> 49 이름으로 호출 (3 + 4) (4 + 3) -> (7) (3 + 4) -> 7 * 7 -> 49 결과는 동일한 단계 내에서 진행한다.

  3. ==============================

    3.이 함수를 호출되기 전에 당신은 단지 값을 정의하고 귀하의 예제의 경우 모든 매개 변수가 평가됩니다. 당신이 이름으로 매개 변수를 정의하려면 당신은 코드 블록을 통과해야한다 :

    이 함수를 호출되기 전에 당신은 단지 값을 정의하고 귀하의 예제의 경우 모든 매개 변수가 평가됩니다. 당신이 이름으로 매개 변수를 정의하려면 당신은 코드 블록을 통과해야한다 :

    def f(x: => Int, y:Int) = x
    

    이 함수에서 호출 될 때까지 매개 변수 x가 평가되지 않습니다 이쪽으로.

    이 작은 포스트는 여기에 잘 이것도을 설명합니다.

  4. ==============================

    4.위의 설명에서 벤의 관점 @ iteratate하기 위해, 나는 그것이 생각하는 것이 최선이라고 생각 "통화별로 이름이"단지 문법적으로. 그들이 사용하는 경우 그들은, 나중에 호출 할 수 있도록 파서는, 익명 함수의 식을 래핑합니다.

    위의 설명에서 벤의 관점 @ iteratate하기 위해, 나는 그것이 생각하는 것이 최선이라고 생각 "통화별로 이름이"단지 문법적으로. 그들이 사용하는 경우 그들은, 나중에 호출 할 수 있도록 파서는, 익명 함수의 식을 래핑합니다.

    사실상 대신 한정

    def callByName(x: => Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    

    실행 :

    scala> callByName(something())
    calling something
    x1=1
    calling something
    x2=1
    

    당신은 또한 다음과 같이 작성할 수있다 :

    def callAlsoByName(x: () => Int) = {
      println("x1=" + x())
      println("x2=" + x())
    }
    

    같은 효과를 다음과 같이하고 실행합니다 :

    callAlsoByName(() => {something()})
    
    calling something
    x1=1
    calling something
    x2=1
    
  5. ==============================

    5.나는 간단한 사용 사례에 의해보다는 예를 제공하여 설명하려고합니다

    나는 간단한 사용 사례에 의해보다는 예를 제공하여 설명하려고합니다

    당신은 당신이 잔소리있어 마지막 시간 이후 때마다 잔소리 것 "잔소리가 심한 여자의 응용 프로그램"을 구축하려는 상상해보십시오.

    다음 구현을 검사 :

    object main  {
    
        def main(args: Array[String]) {
    
            def onTime(time: Long) {
                while(time != time) println("Time to Nag!")
                println("no nags for you!")
            }
    
            def onRealtime(time: => Long) {
                while(time != time) println("Realtime Nagging executed!")
            }
    
            onTime(System.nanoTime())
            onRealtime(System.nanoTime())
        }
    }
    

    이름으로 전달할 때 위의 구현에서 잔소리가 심한 여자에만 작동합니다 이유 값이 전달 될 때 이름 값을 전달할 때하는 변수가 액세스 될 때마다 재 계산된다하면서-재사용되며 따라서 값이 재평가 될 예정이다

  6. ==============================

    6.일반적으로 기능 파라미터 값에 의해 파라미터이고; 이 함수에 전달되기 전에, 즉, 파라미터의 값이 결정된다. 그러나 우리가 매개 변수로는 우리의 함수 내에서 호출 될 때까지 우리는 평가하지 않으려는 표현을 허용하는 함수를 작성해야하는 경우? 이러한 상황의 경우, 스칼라 통화 별 이름 매개 변수를 제공합니다.

    일반적으로 기능 파라미터 값에 의해 파라미터이고; 이 함수에 전달되기 전에, 즉, 파라미터의 값이 결정된다. 그러나 우리가 매개 변수로는 우리의 함수 내에서 호출 될 때까지 우리는 평가하지 않으려는 표현을 허용하는 함수를 작성해야하는 경우? 이러한 상황의 경우, 스칼라 통화 별 이름 매개 변수를 제공합니다.

    호출 - 바이 - 이름기구는 상기 수신자에 코드 블록을 통과 할 때마다 수신자는 코드 블록이 실행되고, 파라미터를 액세스하고, 값이 계산된다.

    object Test {
    def main(args: Array[String]) {
        delayed(time());
    }
    
    def time() = {
      println("Getting time in nano seconds")
      System.nanoTime
    }
    def delayed( t: => Long ) = {
      println("In delayed method")
      println("Param: " + t)
      t
    }
    }
    
     1. C:/>scalac Test.scala 
     2. scala Test
     3. In delayed method
     4. Getting time in nano seconds
     5. Param: 81303808765843
     6. Getting time in nano seconds
    
  7. ==============================

    7.i가 가정 된 바와 같이, 상기 논의와 통화 별 가치 함수는 함수 값을 그냥 통과한다. 마틴 오더 스키에 따르면이 기능 평가에서 중요한 역할을 스칼라에 의한 평가 전략의 후속이다. 그러나, 그것은 간단한 통화로 이름을 확인합니다. 방법에 대한 인수로 자사의 패스와 같은 기능은 고차원-기능으로 알고있다. 상기 방법은 전달 된 파라미터의 값에 액세스 할 때, 전달 함수의 실행을 호출한다. 아래:

    i가 가정 된 바와 같이, 상기 논의와 통화 별 가치 함수는 함수 값을 그냥 통과한다. 마틴 오더 스키에 따르면이 기능 평가에서 중요한 역할을 스칼라에 의한 평가 전략의 후속이다. 그러나, 그것은 간단한 통화로 이름을 확인합니다. 방법에 대한 인수로 자사의 패스와 같은 기능은 고차원-기능으로 알고있다. 상기 방법은 전달 된 파라미터의 값에 액세스 할 때, 전달 함수의 실행을 호출한다. 아래:

    @dhg 예에 따르면, 첫 번째 방법으로 생성 :

    def something() = {
     println("calling something")
     1 // return value
    }  
    

    이 기능은 하나에 println 문을 포함하고 정수 값을 반환합니다. 통화 별 이름으로 인수를 가지고있는 함수를 만듭니다

    def callByName(x: => Int) = {
     println("x1=" + x)
     println("x2=" + x)
    }
    

    이 기능 매개 변수는 하나 개의 정수 값을 반환해야 익명 함수를 정의합니다. 이 X 0 전달 된 인수가 있지만 반환 int 값과 우리의 어떤 기능이 같은 서명이 함수의 정의가 포함되어 있습니다. 우리는 함수를 호출 할 때, 우리는 callByName에 대한 인수로 함수를 전달합니다. 그러나 통화 별 값의 경우에만 해당 함수의 정수 값을 전달한다. 우리는 다음과 같이 함수를 호출 :

    scala> callByName(something())
     calling something
     x1=1
     calling something
     x2=1 
    

    우리가 callByName 방법에 x의 값에 액세스 할 때 때문에 우리의 뭔가 방법은 어떤 방법의 (고화질)과의 통화를 두 번했다.

  8. ==============================

    8.여기에 많은 답변에 의해 설명 된 바와 같이 값에 의한 호출은 일반적으로 사용하는 경우입니다 ..

    여기에 많은 답변에 의해 설명 된 바와 같이 값에 의한 호출은 일반적으로 사용하는 경우입니다 ..

    나는 아래 사용 사례와 이름을 더 간단한 방법으로 전화를 입증하기 위해 노력할 것입니다

    예 1 :

    이름으로 호출의 간단한 예 / 유스 케이스는 경과 시간을 파라미터로 함수를 취해주는 함수, 이하이다.

     /**
       * Executes some code block and prints to stdout the 
    time taken to execute   the block 
    for interactive testing and debugging.
       */
      def time[T](f: => T): T = {
        val start = System.nanoTime()
        val ret = f
        val end = System.nanoTime()
    
        println(s"Time taken: ${(end - start) / 1000 / 1000} ms")
    
        ret
      }
    

    예 2 :

    (스칼라)와 아파치 스파크 이름로서 호출 특성 로깅 참조하여 로깅을 사용 있는 느리게 그 여부를 아래 방법에서 log.isInfoEnabled 여부를 평가한다.

    protected def logInfo(msg: => String) {
         if (log.isInfoEnabled) log.info(msg)
     }
    
  9. ==============================

    9.값에 의한 호출에 상기 식의 값은 함수 호출시에 미리 계산하고 특정 값이 해당 함수에 파라미터로서 전달된다. 같은 값은 모든 기능 전반에 걸쳐 사용됩니다.

    값에 의한 호출에 상기 식의 값은 함수 호출시에 미리 계산하고 특정 값이 해당 함수에 파라미터로서 전달된다. 같은 값은 모든 기능 전반에 걸쳐 사용됩니다.

    이름으로 호출에 반해, 식 자체는 함수의 인자로 전달되고, 이는 단지 특정 파라미터가 호출 될 때마다 기능, 내부 계산된다.

    이름으로 전화 사이의 차이는 더 아래의 예를 들어 이해 될 수있는 스칼라 값에 의해 전화 :

    코드 조각

    object CallbyExample extends App {
    
      // function definition of call by value
      def CallbyValue(x: Long): Unit = {
        println("The current system time via CBV: " + x);
        println("The current system time via CBV " + x);
      }
    
      // function definition of call by name
      def CallbyName(x: => Long): Unit = {
        println("The current system time via CBN: " + x);
        println("The current system time via CBN: " + x);
      }
    
      // function call
      CallbyValue(System.nanoTime());
      println("\n")
      CallbyName(System.nanoTime());
    }
    

    산출

    The current system time via CBV: 1153969332591521
    The current system time via CBV 1153969332591521
    
    
    The current system time via CBN: 1153969336749571
    The current system time via CBN: 1153969336856589
    

    위의 코드에서, 함수는 CallbyValue (System.nanoTime ()) 나노 시스템 시간이 미리 계산하고 미리 계산 된 값은 함수 호출의 파라미터를 전달 된 호출이다.

    그러나 CallbyName (System.nanoTime ()) 함수 호출에서, 식 "System.nanoTime ())"자체는 함수 호출 및 그 표현의 값을 매개 변수로 전달되는 파라미터는 함수 내부에서 사용될 때 계산된다 .

    거기 CallbyName 함수의 함수 정의 주목 A => 기호 매개 변수 x 및 데이터 유형을 분리하는 단계를 포함한다. 기능이 나타냅니다 특정 심볼 이름 유형별로 호출이다.

    즉, 값이 함수 인수로 호출 기능을 들어가기 전에 한 번 평가하고 있지만 이름 함수의 인자에 의해 통화가 필요할 경우에만 함수 내에서 평가됩니다.

    도움이 되었기를 바랍니다!

  10. ==============================

    10.저는 여기에 현재 스칼라의 과정을 복용 나의 동료를 돕기 위해 코딩 간단한 예입니다. 내가 생각 흥미로웠다 것은 마틴 예로 들어 강의에 앞서 제시 한 && 질문의 대답을 사용하지 않은 것입니다. 어쨌든 난이 도움이되기를 바랍니다.

    저는 여기에 현재 스칼라의 과정을 복용 나의 동료를 돕기 위해 코딩 간단한 예입니다. 내가 생각 흥미로웠다 것은 마틴 예로 들어 강의에 앞서 제시 한 && 질문의 대답을 사용하지 않은 것입니다. 어쨌든 난이 도움이되기를 바랍니다.

    val start = Instant.now().toEpochMilli
    
    val calc = (x: Boolean) => {
        Thread.sleep(3000)
        x
    }
    
    
    def callByValue(x: Boolean, y: Boolean): Boolean = {
        if (!x) x else y
    }
    
    def callByName(x: Boolean, y: => Boolean): Boolean = {
        if (!x) x else y
    }
    
    new Thread(() => {
        println("========================")
        println("Call by Value " + callByValue(false, calc(true)))
        println("Time " + (Instant.now().toEpochMilli - start) + "ms")
        println("========================")
    }).start()
    
    
    new Thread(() => {
        println("========================")
        println("Call by Name " + callByName(false, calc(true)))
        println("Time " + (Instant.now().toEpochMilli - start) + "ms")
        println("========================")
    }).start()
    
    
    Thread.sleep(5000)
    

    코드의 출력은 다음과 같이 될 것입니다 :

    ========================
    Call by Name false
    Time 64ms
    ========================
    Call by Value false
    Time 3068ms
    ========================
    
  11. ==============================

    11.파라미터는 보통이 함수 본문에 치환되기 전에 평가 될 것이라는 점을 의미 값에 의해 전달된다.

    파라미터는 보통이 함수 본문에 치환되기 전에 평가 될 것이라는 점을 의미 값에 의해 전달된다.

    당신은 함수를 정의 할 때 이중 화살표를 사용하여 이름으로 전화로 매개 변수를 강제 할 수 있습니다.

    // first parameter will be call by value, second call by name, using `=>`
    def returnOne(x: Int, y: => Int): Int = 1
    
    // to demonstrate the benefits of call by name, create an infinite recursion
    def loop(x: Int): Int = loop(x)
    
    // will return one, since `loop(2)` is passed by name so no evaluated
    returnOne(2, loop(2))
    
    // will not terminate, since loop(2) will evaluate. 
    returnOne(loop(2), 2) // -> returnOne(loop(2), 2) -> returnOne(loop(2), 2) -> ... 
    
  12. ==============================

    12.인터넷에서이 질문에 대한 환상적인 답변을 많이가 이미 있습니다. 난 경우 누군가가 도움이 될 수있는 단지에, 나는 주제에 대해 수집 한 몇 가지 설명과 예제를 컴파일을 작성합니다

    인터넷에서이 질문에 대한 환상적인 답변을 많이가 이미 있습니다. 난 경우 누군가가 도움이 될 수있는 단지에, 나는 주제에 대해 수집 한 몇 가지 설명과 예제를 컴파일을 작성합니다

    소개

    통화별로 값 (CBV)

    일반적으로 기능 파라미터는 호별로 파라미터 값이고; 함수 자체가 평가되기 전에, 즉, 파라미터는 그 값을 결정하기 위해 왼쪽에서 오른쪽으로 평가

    def first(a: Int, b: Int): Int = a
    first(3 + 4, 5 + 6) // will be reduced to first(7, 5 + 6), then first(7, 11), and then 7
    

    통화별로 이름 (CBN)

    그러나 우리가 매개 변수로는 우리의 함수 내에서 호출 될 때까지 우리는 평가하지 않는 표현을 허용하는 함수를 작성해야하는 경우? 이러한 상황의 경우, 스칼라 통화 별 이름 매개 변수를 제공합니다. 그것은이며, 그 평가는 교체 후에 일어나는 파라미터를 의미하는 것은 함수에 전달 될 때

    def first1(a: Int, b: => Int): Int = a
    first1(3 + 4, 5 + 6) // will be reduced to (3 + 4) and then to 7
    

    호출 - 바이 - 이름기구는 호출하는 코드 블록을 통과 할 때마다 호출 코드 블록이 실행되고, 파라미터를 액세스하고, 값이 계산된다. 다음의 예에서, 메시지는, 상기 방법은, 입력 된 것을 보여주는 인쇄 지연. 다음으로, 지문에게 가치있는 메시지를 지연. 마지막으로, 반환 't'를 지연 :

     object Demo {
           def main(args: Array[String]) {
                delayed(time());
           }
        def time() = {
              println("Getting time in nano seconds")
              System.nanoTime
           }
           def delayed( t: => Long ) = {
              println("In delayed method")
              println("Param: " + t)
           }
        }
    

    각각의 경우에 대한 장단점

    CBN : + * * 종료 위 아래 확인 더 자주 종료 + 함수의 인수가 해당 파라미터는 함수 본문의 평가에 사용되지 않는 경우에 평가되지 않는 이점을 가지고 - 그건 느린, 더 클래스를 생성합니다 (프로그램을 의미한다을로드하는 데 시간이 오래 걸립니다) 그리고 더 많은 메모리를 소모합니다.

    CBV : 이 이름은 수반으로 전화를 인수 식의 반복 재 계산을 피할 수 있기 때문에 그것을 + 것은, CBN에 비해 종종 기하 급수적으로 더 효율적입니다. 그것은 단지마다 함수 인수를 평가 당신이 표현이 평가 될 때 훨씬 더 잘 알고 경향이 있기 때문에 + 그것은 절대적으로 효과와 부작용이 훨씬 좋네요한다. - 그것은 그것의 파라미터 평가 중 루프가 발생할 수 * 종단 위 아래 확인 *

    종료는 어떻게 보장되어 있지 않은 경우?

    식 (E)의 -if CBV 평가는 E CBN의 평가도 종료한다 종료 -THE 다른 방향은 사실이 아니다

    비 종단 예

    def first(x:Int, y:Int)=x
    

    제 발현을 고려 (1 루프)

    CBN : 첫 번째 (1, 루프) → 1 CBV : 첫 번째 (1, 루프) →이 표현의 인수를 줄일 수 있습니다. 하나는 루프이기 때문에, infinivly 인수를 줄일 수 있습니다. 그것은 종료되지 않습니다

    각각의 경우의 행동의 차이

    될 것의이 방법 테스트를 정의 할 수

    Def test(x:Int, y:Int) = x * x  //for call-by-value
    Def test(x: => Int, y: => Int) = x * x  //for call-by-name
    

    사례 1 시험 (2,3)

    test(2,3)   →  2*2 → 4
    

    우리는 이미 평가 인수로 시작하기 때문에이 호출 별 값을 단계의 동일한 금액을하고 통화-이름으로합니다

    Case2 시험 (3 + 4,8)

    call-by-value: test(3+4,8) → test(7,8) → 7 * 7 → 49
    call-by-name: (3+4)*(3+4) → 7 * (3+4) → 7 * 7 → 49
    

    이 경우 호출 - 바이 - 값 이하 단계를 수행

    Case3 시험 (7, 2 * 4)

    call-by-value: test(7, 2*4) → test(7,8) → 7 * 7 → 49
    call-by-name: (7)*(7) → 49
    

    우리는 두 번째 인수의 불필요한 계산을 피하기

    Case4 시험 (3 + 4, 2 * 4)

    call-by-value: test(7, 2*4) → test(7,8) → 7 * 7 → 49
    call-by-name: (3+4)*(3+4) → 7*(3+4) → 7*7 →  49
    

    다른 접근 방식

    첫째, 우리가 부작용으로 함수가 있다고 가정하자. 이 기능은 뭔가를 출력 한 다음 int를 돌려줍니다.

    def something() = {
      println("calling something")
      1 // return value
    }
    

    (: Int 인 X)과 (전화 별 이름 스타일 다른 X 이제 우리는 하나가 통화 별 가치 스타일의 인수를 제외하고는 정확히 동일 지능의 인수를 사용할 두 개의 함수를 정의하려고 : => INT).

    def callByValue(x: Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    def callByName(x: => Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    

    우리가 우리의 옆을 초래 함수를 호출 할 때 지금 무슨 일이?

    scala> callByValue(something())
    calling something
    x1=1
    x2=1
    scala> callByName(something())
    calling something
    x1=1
    calling something
    x2=1
    

    그래서 당신은 통화 별 값 버전에서 그것을 볼 수 전달 된 함수 호출의 부작용 (뭔가 ()) 한 번만 발생했습니다. 그러나, 통화 별 이름 버전, 부작용은 두 번 일어났다.

    통화 별 값 함수는 함수를 호출하기 전에 전달 된 표현의 값을 계산하기 때문에, 따라서 같은 값이 때마다 액세스 할 수있다. 그러나 통화로 이름 기능은 전달 된 표현의 가치가 액세스 할 때마다 재 계산.

    IT는 더 나은 예는 CALL-BY-이름을 사용

    올린 사람 : https://stackoverflow.com/a/19036068/1773841

    간단한 성능 예 : 로깅.

    의이 같은 인터페이스를 가정 해 봅시다 :

    trait Logger {
      def info(msg: => String)
      def warn(msg: => String)
      def error(msg: => String)
    }
    

    그리고 다음과 같이 사용 :

    logger.info("Time spent on X: " + computeTimeSpent)
    

    (예를 들어, 로깅 수준이보다 높은에 대해 구성된 때문에)에서 정보 방법은 아무것도하지 않는 경우, computeTimeSpent은 시간을 절약 호출되지 없구요. 이 일이 종종 작업이 기록되는 고가의 상대가 될 수 문자열 조작을보고 로거와 많이 발생합니다.

    정확성 예 : 논리 연산자.

    당신은 아마 다음과 같은 코드를 보았다 :

    if (ref != null && ref.isSomething)
    

    이 같은 && 방법을 선언하는 것입니다 상상 :

    trait Boolean {
      def &&(other: Boolean): Boolean
    }
    

    심판 널 때마다 isSomething가 &&에 전달되기 전에 nullreference에서 호출되기 때문에 다음, 오류가 발생합니다. 이러한 이유로, 실제 선언은 다음과 같습니다

    trait Boolean {
      def &&(other: => Boolean): Boolean =
        if (this) this else other
    }
    
  13. ==============================

    13.예를가는 것은 당신이 더 차이를 이해하는 데 도움이됩니다.

    예를가는 것은 당신이 더 차이를 이해하는 데 도움이됩니다.

    의 현재 시간을 반환하는 간단한 기능을 definie 보자 :

    def getTime = System.currentTimeMillis
    

    이제 우리는 두 번째 지연을 두 번 인쇄 이름으로 함수를 정의 할 수 있습니다 :

    def getTimeByName(f: => Long) = { println(f); Thread.sleep(1000); println(f)}
    

    가치에 의하여 한 :

    def getTimeByValue(f: Long) = { println(f); Thread.sleep(1000); println(f)}
    

    이제 각을 부르 자 :

    getTimeByName(getTime)
    // prints:
    // 1514451008323
    // 1514451009325
    
    getTimeByValue(getTime)
    // prints:
    // 1514451024846
    // 1514451024846
    

    그 결과의 차이를 설명해야한다. 코드 조각은 여기에서 확인할 수 있습니다.

  14. ==============================

    14.사용하는 경우 CallByName가 호출되고 문이 발견 될 때마다 callByValue가 호출됩니다.

    사용하는 경우 CallByName가 호출되고 문이 발견 될 때마다 callByValue가 호출됩니다.

    예를 들면 : -

    우리가 스칼라 프롬프트를 얻을하지 않습니다이 기능을 실행하면 나는, 즉 무한 루프가 있습니다.

    scala> def loop(x:Int) :Int = loop(x-1)
    loop: (x: Int)Int
    

    callByName 함수는 인수로 루프 방법 이상 걸리며 그 몸체 내부에 사용되지 않는다.

    scala> def callByName(x:Int,y: => Int)=x
    callByName: (x: Int, y: => Int)Int
    

    callByName 기능 내부 루프 기능을 사용하여 어디 우리가 더이기 때문에 우리가 어떤 문제를 찾을 수없는 callByName 방법의 실행에 (우리는 스칼라 프롬프트 다시를 얻을 수 없음).

    scala> callByName(1,loop(10))
    res1: Int = 1
    scala> 
    

    callByValue 함수를 반복적으로 실행하여 루프 기능이 외부 함수를 실행하기 전에 평가 기능 또는 발현 내측 결과 파라미터로 상기 루프 방법 취하고 우리 스칼라 프롬프트를 다시 얻을 수 없다.

    scala> def callByValue(x:Int,y:Int) = x
    callByValue: (x: Int, y: Int)Int
    
    scala> callByValue(1,loop(1))
    
  15. ==============================

    15.이것 좀 봐:

    이것 좀 봐:

        object NameVsVal extends App {
    
      def mul(x: Int, y: => Int) : Int = {
        println("mul")
        x * y
      }
      def add(x: Int, y: Int): Int = {
        println("add")
        x + y
      }
      println(mul(3, add(2, 1)))
    }
    

    Y => 지능 이름으로 호출된다. 어떤 이름으로 호출로 전달된다 (2, 1)을 추가합니다. 이 게으르게 평가됩니다. 추가가 먼저 호출하는 것처럼 보이지만 그래서 콘솔 출력은 "추가"다음에 "MUL"입니다. 이름으로 전화가 같은 종류의 함수 포인터를 전달하는 역할을합니다. => Int 인 y로 : : 이제 Y에서 변경 지능. 콘솔은 "추가", "MUL"다음에 표시됩니다! 평가의 일반적인 방법입니다.

  16. ==============================

    16.나는 여기에 모든 해답을 생각하는 올바른 정당성을하지 않는다 :

    나는 여기에 모든 해답을 생각하는 올바른 정당성을하지 않는다 :

    호출에서 값으로 인수 한 번만 계산된다 :

    def f(x : Int, y :Int) = x
    
    // following the substitution model
    
    f(12 + 3, 4 * 11)
    f(15, 4194304)
    15
    

    당신은 일반적으로 통화에 의해 값이 빠른 항상은 아니지만이 경우처럼 될 수 있고, 모든 인수가 아닌지 필요로 평가되는 이상 볼 수 있습니다.

    평가 방법 이었다면 통화 별 이름은 다음 분해했을 것이다 :

    f(12 + 3, 4 * 11)
    12 + 3
    15
    

    우리는 4 * 11를 평가하는 데 필요하지 따라서 때로는 도움이 될 수 계산의 비트를 저장 결코 위에 당신은 볼 수 있습니다.

  17. from https://stackoverflow.com/questions/13337338/call-by-name-vs-call-by-value-in-scala-clarification-needed by cc-by-sa and MIT license