복붙노트

[SCALA] 스칼라 함수를 정의하는 두 가지 방법. 차이점은 무엇입니까?

SCALA

스칼라 함수를 정의하는 두 가지 방법. 차이점은 무엇입니까?

여기에 정의하고 일부 기능을 시도 약간의 스칼라 세션은 다음과 같습니다

scala> def test1(str: String) = str + str;    
test1: (str: String)java.lang.String

scala> test1("ab")
res0: java.lang.String = abab

잘 작동합니다.

scala> val test2 = test1
<console>:6: error: missing arguments for method test1 in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
       val test2 = test1
                   ^

죄송합니다.

scala> val test2 = test1 _
test2: (String) => java.lang.String = <function1>

scala> test2("ab")
res1: java.lang.String = abab

잘 작동합니다!

(_ + _ 등) 접이식 때 지금, 나는 _ 구문을 보았다. 나는 그것이 _ 기본적으로 "인수"를 의미 이해 그래서. 그래서 TEST1 _ _ 기본적으로 "TEST1하기 위해 주어진 인수와 함수를 의미한다. 그러나 나는를 추가하는 경우 그 이유는 왜 차이가? 정확히 단지 TEST1과 동일하지 않습니다?

그래서 나는 탐구 유지 ...

scala> val test3 = (str: String) => str + str
test3: (String) => java.lang.String = <function1>

scala> test3("ab")
res2: java.lang.String = abab

scala> val test4 = test3
test4: (String) => java.lang.String = <function1>

여기가 _없이 작동! 정의 기능, 유효한 기능의 차이는 무엇인가?

해결법

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

    1.def'ed 기능과 val'ed 기능에는 차이가 없습니다 :

    def'ed 기능과 val'ed 기능에는 차이가 없습니다 :

    scala> def test1 = (str: String) => str + str
    test1: (String) => java.lang.String
    
    scala> val test2 = test1
    test2: (String) => java.lang.String = <function1>
    
    scala> val test3 = (str: String) => str + str
    test3: (String) => java.lang.String = <function1>
    
    scala> val test4 = test2
    test4: (String) => java.lang.String = <function1>
    

    보다? 이들 모두는 그들이 가지고 = X> Y 형으로 표시되는 함수이다.

    scala> def test5(str: String) = str + str
    test5: (str: String)java.lang.String
    

    당신은 X => Y 유형을 볼 수 있습니까? 당신이 경우에 아무도 없기 때문에, 안과 참조 이동합니다. 타입은 일반적으로 여기하는 방법을 나타 내기 위해 사용 (X) Y이다.

    사실, TEST1, TEST2, TEST3 및 테스트 4는 기능을 반환하는 모든 방법이 있습니다. test5는 java.lang.String의를 반환하는 방법이다. test5는 않지만 또한, TEST4 통해 TEST1은 (단지 TEST1 수 있었다, 어쨌든) 매개 변수를 사용하지 않습니다.

    그래서, 그 차이는 아주 간단합니다. 첫 번째 경우, 당신은 발에 메서드를 지정하려고했으나 방법이 걸릴 매개 변수를 입력하지 않았다. 당신이 함수에 내 방법을 켜 의미 뒤에 밑줄을 추가 할 때까지 그래서, 실패했습니다.

    두 번째 예제에서는 함수를 가지고, 그래서 당신은 다른 작업을 수행 할 필요가 없습니다.

    방법은 함수와 그 반대하지 않습니다. 함수는 FunctionN 클래스 중 하나의 목적이다. 방법은 객체와 관련된 코드의 일부 조각에 대한 핸들입니다.

    스택 오버플 방법 대 기능에 대한 다양한 질문을 참조하십시오.

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

    2.수비력은 자바의 메소드를 정의하는 방식과 유사 주변 객체 / 클래스 / 특성 내에서 방법을 선언합니다. 당신은 다른 객체 / 클래스 / 특성에서 인증 된 정의를 사용할 수 있습니다. REPL, 그것은 "숨겨진"때문에 당신은 주변의 물체를 볼 수 있지만, 그것은 존재한다.

    수비력은 자바의 메소드를 정의하는 방식과 유사 주변 객체 / 클래스 / 특성 내에서 방법을 선언합니다. 당신은 다른 객체 / 클래스 / 특성에서 인증 된 정의를 사용할 수 있습니다. REPL, 그것은 "숨겨진"때문에 당신은 주변의 물체를 볼 수 있지만, 그것은 존재한다.

    수비력이 값이 아니기 때문에 당신은 값에 고화질을 할당 할 수 없습니다 - 그것은 개체의 방법입니다.

    및 (x : T는) => X * X 선언 런타임에있는 함수 객체를 인스턴스화한다. 함수 객체는 FunctionN 특성을 확장 익명 클래스의 인스턴스입니다. FunctionN 특성은 적용 방법이 제공됩니다. 이 생략 될 수 있기 때문에 적용 이름은 특별하다. 식 F (x)는 f.apply에 desugared된다 (X).

    최하위입니다 - 함수 객체가 힙에 존재하는 런타임 값이기 때문에, 당신은 값, 변수 및 매개 변수에 할당, 또는 반환 값으로 방법에서 그들을 반환 할 수 있습니다.

    값 (유용 할 수 있음)에 할당하는 방법의 문제를 해결하기 위해, 스칼라는 방법에서 함수 객체를 생성하도록 자리 문자를 사용할 수있다. 식 TEST1 _ 실제로이 방법 TEST1 래퍼 함수를 ​​생성 위 예에서 -는 X => TEST1 (X)에 상당한다.

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

    3.밑줄은 서로 다른 상황에서 다른 것을 의미한다. 그러나 항상 여기 것이지만, 필요하지 않는 것은이 이름이 될으로 간주 할 수 있습니다.

    밑줄은 서로 다른 상황에서 다른 것을 의미한다. 그러나 항상 여기 것이지만, 필요하지 않는 것은이 이름이 될으로 간주 할 수 있습니다.

    파라미터 대신에 적용하면 효과가 기능하는 방법을 올릴 것이다.

    scala> def test1(str: String) = str + str; 
    test1: (str: String)java.lang.String
    
    scala> val f1 = test1 _
    f1: (String) => java.lang.String = <function1>
    

    참고있어서 타입의 함수 (문자열) => 문자열되었다.

    방법 및 스칼라의 함수 사이의 구분이 방법은 기존의 Java 메소드에 가깝다는 것이다. 당신은 값으로 그 주위에 전달할 수 없습니다. 기능은 자신의 권리를 값이며, 입력 매개 변수와 반환 값으로 사용할 수는 있지만.

    리프팅은 더 갈 수 있습니다 :

    scala> val f2 = f1 _
    f2: () => (String) => java.lang.String = <function0>
    

    이 기능을 해제하는 것은 다른 함수가 발생합니다. 유형의이 시간 () => (문자열) => (문자열)

    내가 말할 수있는 건,이 구문은 명시 적으로 밑줄로 모든 매개 변수를 대체하는 것과 동일합니다. 예를 들면 :

    scala> def add(i: Int, j: Int) = i + j
    add: (i: Int,j: Int)Int
    
    scala> val addF = add(_, _)
    addF: (Int, Int) => Int = <function2>
    
    scala> val addF2 = add _    
    addF2: (Int, Int) => Int = <function2>
    
  4. from https://stackoverflow.com/questions/5009411/two-ways-of-defining-functions-in-scala-what-is-the-difference by cc-by-sa and MIT license