복붙노트

[SCALA] 무엇 =의 차이> () =>, 그리고 단위 =>

SCALA

무엇 =의 차이> () =>, 그리고 단위 =>

내가 인수를 취하지 않으며 값을 반환하는 함수를 표현하기 위해 노력하고있어 (당신이 알고해야하는 경우 나, 자바 스크립트에서의 setTimeout 기능을 시뮬레이션하고 있습니다.)

case class Scheduled(time : Int, callback :  => Unit)

"발 '매개 변수는 통화로 이름 할 수 없습니다'"라고, 컴파일되지 않습니다

case class Scheduled(time : Int, callback :  () => Unit)  

컴파일하지만 대신에, 이상하게 호출 할 수있다

Scheduled(40, { println("x") } )

나는이 작업을 수행해야

Scheduled(40, { () => println("x") } )      

무엇도 작동하는 것은

class Scheduled(time : Int, callback :  Unit => Unit)

하지만 짝수 덜 합리적인 방법으로 호출

 Scheduled(40, { x : Unit => println("x") } )

(유형 단위의 변수는 무엇을 할 것인가?) 내가 물론 원하는 것은 그것이 일반 기능이라면 나는 그것을 호출 할 방법을 호출 할 수있는 생성자입니다 :

 Scheduled(40, println("x") )

아기에게 자신의 병을 줘!

해결법

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

    1.=> 유형 표기법 통화 별 이름 매개 변수가 전달 될 수있는 많은 방법 중 하나입니다, 의미합니다. 당신이 그들에 익숙하지 않은 경우, 나는 그 위키 피 디아 기사를 읽을 시간을 복용하는 것이 좋습니다 심지어 요즘 비록입니다 대부분에 의해-가치 전화 통화에 의해 참조.

    => 유형 표기법 통화 별 이름 매개 변수가 전달 될 수있는 많은 방법 중 하나입니다, 의미합니다. 당신이 그들에 익숙하지 않은 경우, 나는 그 위키 피 디아 기사를 읽을 시간을 복용하는 것이 좋습니다 심지어 요즘 비록입니다 대부분에 의해-가치 전화 통화에 의해 참조.

    무엇을 의미하는 것은 어떤 전달하는 것은 함수 내부 값 이름으로 대체된다는 점이다. 예를 들어,이 기능을 가지고 :

    def f(x: => Int) = x * x
    

    나는 다음과 같이 호출하면

    var y = 0
    f { y += 1; y }
    

    그런 다음 코드는 다음과 같이 실행됩니다

    { y += 1; y } * { y += 1; y }
    

    그는 식별자 이름 충돌이 있다면 어떤 일이 일어나는지 점을 제기했지만. 기존의 통화 별 이름으로, 메커니즘 캡처 회피 대체 이름 충돌을 방지하기 위해 발생했다. 스칼라 그러나이 같은 결과로 다른 방식으로 구현 - 파라미터 내부 식별자 이름은 함수 호출이나 그림자 식별자를 참조 할 수있다.

    통화로 이름을 내가 다른 두를 설명 후의 말 것이다 관련된 몇 가지 다른 점이있다.

    구문은 () => 유형은 Function0의 유형을 의미합니다. 즉, 매개 변수를 사용하지 않는 무언가를 반환하는 함수이다. 이 방법의 크기 ()를 호출, 말과 동일합니다 -이 매개 변수를 사용하지 않는 및 숫자를 반환합니다.

    그것은이 구문은 혼란의 원인이다 리터럴 익명 함수, 구문과 매우 유사하다, 그러나, 재미있다. 예를 들어,

    () => println("I'm an anonymous function")
    

    그 유형의 인수에 대응 0 리터 익명 함수이고,

    () => Unit
    

    그래서 우리가 쓸 수 있습니다 :

    val f: () => Unit = () => println("I'm an anonymous function")
    

    그러나, 값 유형을 혼동하지 않는 것이 중요합니다.

    이것은 실제로 그 첫 번째 매개 변수 타입 단위입니다 단지 기능 1입니다. 그것이 될 것입니다 쓸 수있는 다른 방법 (단위) => 입력하거나 기능 1 [단위, 종류]. 문제는이 이제까지 사람이 원하는 것을 할 가능성은 ...입니다. 단위 유형의 주요 목적은 그래서 그 값을받을 수 이해가되지 않습니다, 하나에 관심이없는 값을 표시한다.

    예를 들어, 고려,

    def f(x: Unit) = ...
    

    하나의 가능성이 X로 무엇을 할 수 있습니까? 그것은 단지 하나의 값을 가질 수 있습니다, 그래서 하나는 그것을받을 필요가 없다. 한 가지 가능한 사용 단위를 리턴하는 함수 체인 될 것이다 :

    val f = (x: Unit) => println("I'm f")
    val g = (x: Unit) => println("I'm g")
    val h = f andThen g
    

    andThen 만 기능 1에 정의 된, 우리는 장치를 반송되는 연쇄 된 기능, 우리는 입력 기능 1 [수량, 단위]의 존재로 정의했다되므로 체인 그들 수있다.

    혼란의 첫 번째 소스는 통화별로 이름이 존재 0 인수에 대응 기능을 위해 존재 종류와 문자 사이의 유사성을 생각합니다. 즉, 때문에, 그 생각

    () => { println("Hi!") }
    

    () 리터럴 => 유닛은, 인

    { println("Hi!") }
    

    => 단위에 대한 문자 그대로 될 것이다. 그것은 아니다. 즉 코드 블록이 아닌 문자입니다.

    혼란의 또 다른 소스는 단위 유형의 값은 (), 0-인수에 대응 매개 변수 목록처럼 보인다하여 기록되어있다 (하지만하지 않습니다).

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

    2.

    case class Scheduled(time : Int, callback :  => Unit)
    

    이 사건의 수정은 생성자에 각 인수에서 암시 발을합니다. 당신은 통화 별 이름 매개 변수를 사용할 수 있습니다 케이스를 제거하면 따라서 (같은 사람이 언급). 컴파일러는 아마 어쨌든 그것을 허용 할 수 있지만, 대신에 게으른 발 콜백 변신의 발 콜백을 만든 경우는 사람들을 놀라게 수 있습니다.

    당신이 콜백을 변경하는 경우 : () => 단위는 이제 귀하의 경우는 통화별로 이름 매개 변수보다는 기능을합니다. 아무 문제가 없다, 그래서 분명히 함수가 발 콜백에 저장할 수 있습니다.

    가장 쉬운 방법은 당신이 원하는 것을 얻을 수 있습니다 (예약 (40,에 println ( "X"))를 호출하여 이름 매개 변수는 람다를 전달하는 데 사용되는 경우)의 경우를 생략하고 명시 적으로 당신이 '나오지 않았어 것을 적용 만들 아마 t는 처음에 얻을 :

    class Scheduled(val time: Int, val callback: () => Unit) {
        def doit = callback()
    }
    
    object Scheduled {
        def apply(time: Int, callback: => Unit) =
            new Scheduled(time, { () => callback })
    }
    

    사용:

    scala> Scheduled(1234, println("x"))
    res0: Scheduled = Scheduled@5eb10190
    
    scala> Scheduled(1234, println("x")).doit
    x
    
  3. ==============================

    3.질문, 당신은 자바 스크립트의 setTimeout 기능을 시뮬레이션 할 수 있습니다. 이전 답변을 바탕으로, 나는 코드를 다음 쓰기 :

    질문, 당신은 자바 스크립트의 setTimeout 기능을 시뮬레이션 할 수 있습니다. 이전 답변을 바탕으로, 나는 코드를 다음 쓰기 :

    class Scheduled(time: Int, cb: => Unit) {
      private def runCb = cb
    }
    
    object Scheduled {
      def apply(time: Int, cb: => Unit) = {
        val instance = new Scheduled(time, cb)
        Thread.sleep(time*1000)
        instance.runCb
      }
    }
    

    REPL에서, 우리는 다음과 같이 얻을 수 있습니다 :

    scala> Scheduled(10, println("a")); Scheduled(1, println("b"))
    a
    b
    

    우리의 시뮬레이션 기능을 차단하고 있기 때문에 우리의 시뮬레이션은 정확히에서는 setTimeout과 같은 행동을하지 않지만에서는 setTimeout 비 차단하고 있습니다.

  4. from https://stackoverflow.com/questions/4543228/whats-the-difference-between-and-unit by cc-by-sa and MIT license