2011-04-28 5 views
7

나는 이해할 수없는 이상한 상황에 처해있다. 저는 "Programming in Scala"책을 읽고 있습니다, Ch. 9.카레 기능이 이상한 물건

의이 나는 카레 기능을 가지고 있다고 가정 해 봅시다 : 나는 경우,

withThis(5){ 
    (x) => {println("Hello!"); println(x); } 
} 
// Outputs 
Before 
Hello! 
5 
After 

그러나 : 내가 예상했던대로 작동 특별한 곱슬 구문 내에서 하나 개의 인자로 호출

def withThis(n:Int)(op:Int=>Unit){ 
     println("Before") 
     op(n); 
     println("After") 
} 

두 문장을 넣어, 나는 뭔가 wierd를 얻을 :

withThis(5){ 
    println("Hello!") 
    println(_) 
} 
// Outputs 
Hello! 
Before 
5 
After 

어떻게 "와서!" "Before"와 "5"가 인쇄되기 전에 인쇄됩니까? 내가 미쳤 니?

답변

10

귀하의 마지막 코드 예제가 예상 된 결과 생산하기 위해 다음과 같이 다시 작성해야 반환 그렇지 않으면

withThis(5) { x => 
    println("Hello!") 
    println(x) 
} 

를, 당신의 예는 자리로

withThis(5) { 
    println("Hello!") 
    (x: Int) => println(x) 
} 

에 해당 _ 될 것입니다 가능한 한 단단히 묶어서 비 축퇴 된 방식으로 (예 : println(x => x)으로 확장되지 않음) 확장됩니다.

주목할 점은 블록이 항상 마지막 값을 반환한다는 것입니다. 귀하의 예에서 마지막 값은 실제로 (x: Int) => println(x)입니다.

+2

하지만 println (x => x)은 올바른 구문이 아닙니다. 어쨌든 - 나는 println (_)이하는 일을 이해합니다 - 저는이 "블록"사업에 대해 더 혼란 스러웠습니다. – drozzy

+0

구문이 정확합니다. 이 경우에는 매개 변수 유형이 없어서 컴파일되지 않지만 컴파일러에서 유추 할 수있는 경우에는 작동합니다. 간단한 예 :'def doit (f : Int => Int) =(); doit (x => x)' –

+0

나는 그것이 "(x : Int) => println (x)"과 동등하다는 것을 안다. 나의 질문은 실제로 println을 먼저 실행하는 이유이다. "블록은 항상 마지막 값을 반환합니다"라고 대답 한 것 같습니다. 블록이 느슨하게 평가되지 않는다는 것을 의미합니까? – drozzy

3

두 번째 예에서 줄 바꿈 부분 : { println("Hello!"); println(_) }은 "Hello!"를 인쇄하는 블록입니다. 카레를 반환합니다 println. 상상해보십시오. { println("Hello!"); 5 }, "Hello!" 5.

+0

나는 책에서 "블록"부분을 아직 생각하지 않는다. 그래서 나는 아마 혼란 스럽다. – drozzy

+0

두 번째 예제에서 예상대로 작동하도록 할 방법이 없습니까? 이름 별 매개 변수로 시도했지만 논쟁을하지 않습니다. – drozzy

+0

그냥 까다 롭습니다. 블록은 "카 트리트 된 println'"을 반환하지 않지만 인수가있는 println을 호출하는 하나의 인수를 가진 익명의 함수를 반환합니다. –

관련 문제