[SCALA] 함수를 정의하는 "DEF"와 "발"의 차이점은 무엇입니까
SCALA함수를 정의하는 "DEF"와 "발"의 차이점은 무엇입니까
차이 사이는 무엇입니까 :
def even: Int => Boolean = _ % 2 == 0
과
val even: Int => Boolean = _ % 2 == 0
두도 (10)처럼 호출 할 수 있습니다.
해결법
-
==============================
1.방법 데프도 통화를 평가하고 새로운 기능마다 (기능 1의 새로운 인스턴스)를 생성한다.
방법 데프도 통화를 평가하고 새로운 기능마다 (기능 1의 새로운 인스턴스)를 생성한다.
def even: Int => Boolean = _ % 2 == 0 even eq even //Boolean = false val even: Int => Boolean = _ % 2 == 0 even eq even //Boolean = true
데프하면 호출 할 때마다 새로운 기능을 얻을 수 있습니다 :
val test: () => Int = { val r = util.Random.nextInt () => r } test() // Int = -1049057402 test() // Int = -1049057402 - same result def test: () => Int = { val r = util.Random.nextInt () => r } test() // Int = -240885810 test() // Int = -1002157461 - new result
정의 할 때 발 데프, 평가 - 전화했을 때 :
scala> val even: Int => Boolean = ??? scala.NotImplementedError: an implementation is missing scala> def even: Int => Boolean = ??? even: Int => Boolean scala> even scala.NotImplementedError: an implementation is missing
게으른 발 : 세 번째 옵션이 있습니다.
처음 전화했을 때 그것은 평가 :
scala> lazy val even: Int => Boolean = ??? even: Int => Boolean = <lazy> scala> even scala.NotImplementedError: an implementation is missing
그러나 모든 시간 (기능이 경우 동일한 인스턴스에서) 동일한 결과를 반환합니다 :
lazy val even: Int => Boolean = _ % 2 == 0 even eq even //Boolean = true lazy val test: () => Int = { val r = util.Random.nextInt () => r } test() // Int = -1068569869 test() // Int = -1068569869 - same result
공연
정의 할 때 발은 평가합니다.
데프는 모든 통화를 평가하므로 성능은 여러 통화에 발보다 더 될 수 있습니다. 단일 통화와 동일한 성능을 얻을 수 있습니다. 그리고 어떤 통화를 사용하면 데프에서 오버 헤드를 얻을 것이다, 그래서 당신은 어떤 지점에서 그것을 사용하지 않을 경우에도 당신은 그것을 정의 할 수 있습니다.
게으른 발하면 게으른 평가를 얻을 것이다 : 당신이 어떤 지점에서 그것을 사용하지 않을 경우에도 당신은 그것을 정의 할 수 있으며, 한 번 또는 전혀 평가,하지만 당신에 대한 모든 액세스를 두 번 확인 잠금에서 약간의 오버 헤드를 얻을 수 있습니다 당신의 게으른 발.
@SargeBorsch가 언급 한 바와 같이 당신이 방법을 정의 할 수 있습니다, 이것은 가장 빠른 방법입니다 :
def even(i: Int): Boolean = i % 2 == 0
하지만이 기능 성분 또는 고차 기능에 대한 기능 (하지 방법)이 필요한 경우 (필터처럼 (심지어)) 컴파일러는 당신의 방법에서 함수 당신이 기능으로 사용 때마다 생성되므로 성능이보다 약간 더 악화 될 수 있습니다 발.
-
==============================
2.이걸 고려하세요:
이걸 고려하세요:
scala> def even: (Int => Boolean) = { println("def"); (x => x % 2 == 0) } even: Int => Boolean scala> val even2: (Int => Boolean) = { println("val"); (x => x % 2 == 0) } val //gets printed while declaration. line-4 even2: Int => Boolean = <function1> scala> even(1) def res9: Boolean = false scala> even2(1) res10: Boolean = false
당신은 차이를 볼 수 있습니까? 한마디로 :
정의 : 모든 호출의 경우에도, 그것은 다시 심지어 방법의 몸을 호출합니다. 그러나 even2 즉 발과 함께 함수 선언 (그리고 따라서 그것은 결코 다시 라인 (4)에서 발을 인쇄 등) 동안 단지 한번 초기화되어 동일한 출력은 액세스 할 때마다 사용된다. 예를 들어이 일을 시도 :
scala> import scala.util.Random import scala.util.Random scala> val x = { Random.nextInt } x: Int = -1307706866 scala> x res0: Int = -1307706866 scala> x res1: Int = -1307706866
X가 초기화되면 Random.nextInt 의해 반환 된 값이 X의 최종 값으로 설정된다. 다음 시간 x는 다시 사용, 항상 같은 값을 반환합니다.
또한 게으르게 X를 초기화 할 수 있습니다. 그것을 사용하는, 즉 처음 초기화되지 동안 선언된다. 예를 들면 :
scala> lazy val y = { Random.nextInt } y: Int = <lazy> scala> y res4: Int = 323930673 scala> y res5: Int = 323930673
-
==============================
3.이것 좀 봐:
이것 좀 봐:
var x = 2 // using var as I need to change it to 3 later val sq = x*x // evaluates right now x = 3 // no effect! sq is already evaluated println(sq)
놀랍게도,이 4가 아닌 구를 인쇄합니다! 발 (심지어 VAR)는 즉시 평가 할당됩니다. 지금은 9 인쇄합니다 .. 수비력 발을 변경! 데프는 함수 호출 .. 그것을 호출 할 때마다 평가하는 것입니다.
-
==============================
4.스칼라 정의 고정하여 브로 즉 "스퀘어"입니다. 그것은 바로 신고시 평가, 나중에 변경할 수 없습니다. 이 INT 타입 있지 않도록 또한 even2 발하지만, 함수, 즉 서명 "(INT => 부울)"로 선언 된 다른 실시 예에서는. 이 함수이며이 값은 다음의 식에 의해 설정되어있어
스칼라 정의 고정하여 브로 즉 "스퀘어"입니다. 그것은 바로 신고시 평가, 나중에 변경할 수 없습니다. 이 INT 타입 있지 않도록 또한 even2 발하지만, 함수, 즉 서명 "(INT => 부울)"로 선언 된 다른 실시 예에서는. 이 함수이며이 값은 다음의 식에 의해 설정되어있어
{ println("val"); (x => x % 2 == 0) }
스칼라 발 특성에 따라, 당신은 even2, 평방와 같은 규칙에 다른 기능을 할당 할 수 없습니다.
또 다시 "발"을 인쇄하지 eval2의 발 함수를 호출하는 이유에 대해?
오리지널 코드 :
val even2: (Int => Boolean) = { println("val"); (x => x % 2 == 0) }
우리는 표현의 위 종류의 스칼라에서 마지막 문을 알고 (내부 {..}) 실제로 왼쪽으로 돌아된다. 그래서 당신은에 "X => X % 2 == 0"당신은 즉 even2 발 유형 (INT => 부울)에 대한 선언 된 형태와 일치하는 기능, 그래서 컴파일러는 행복 even2 설정을 끝낸다. 지금 만 포인트를 even2 "(X => X % 2 == 0)"기능 (예에 println ( "발"이전되지 않은 다른 문) 등 실제로 호출합니다 서로 다른 매개 변수와 함께 event2 호출 "(X => X 2 % == 0) "코드뿐만 아니라이 event2로 저장됩니다.
scala> even2(2) res7: Boolean = true scala> even2(3) res8: Boolean = false
그냥이 더 명확히하기 위해, 다음과 같은 코드의 다른 버전입니다.
scala> val even2: (Int => Boolean) = { | println("val"); | (x => { | println("inside final fn") | x % 2 == 0 | }) | }
무슨 일이 일어날 것 ? 여기에 우리는 당신이 even2를 호출 할 때 (), 다시하고 다시 인쇄 "최종 FN 내부"를 참조하십시오.
scala> even2(3) inside final fn res9: Boolean = false scala> even2(2) inside final fn res10: Boolean = true scala>
-
==============================
5.이러한 데프 X = 전자로 정의를 실행하면 표현 전자를 평가하지 않습니다. X가 호출 될 때마다 인 - 대신 전자는 평가된다.
이러한 데프 X = 전자로 정의를 실행하면 표현 전자를 평가하지 않습니다. X가 호출 될 때마다 인 - 대신 전자는 평가된다.
또한, 스칼라 값의 정의를 제공합니다 정의의 평가의 일부로서 오른쪽 측면을 평가할 않는 발 X = E. X는 차후에 사용되면 발현이 다시 계산 될 필요가 없도록, 그 즉시, E의 사전 계산 된 값으로 대체된다.
-
==============================
6.또한, 발 가치 평가에 의한 것이다. 어느 우측식이 정의 중에 평가 수단. 어디 데프 이름 평가입니다. 그것이 사용되는 때까지 평가되지 않습니다.
또한, 발 가치 평가에 의한 것이다. 어느 우측식이 정의 중에 평가 수단. 어디 데프 이름 평가입니다. 그것이 사용되는 때까지 평가되지 않습니다.
-
==============================
7.위의 도움이 답변뿐만 아니라, 내 연구 결과는 다음과 같습니다
위의 도움이 답변뿐만 아니라, 내 연구 결과는 다음과 같습니다
def test1: Int => Int = { x => x } --test1: test1[] => Int => Int def test2(): Int => Int = { x => x+1 } --test2: test2[]() => Int => Int def test3(): Int = 4 --test3: test3[]() => Int
위는 "DEF"를 호출 할 때 다른 기능 "지능 ="지능 "반환 (영 인자 매개 변수) 방법임을 보여준다.
기능에 대한 방법의 전환은 물론 여기에 설명 : https://tpolecat.github.io/2014/06/09/methods-functions.html
-
==============================
8.REPL에서,
REPL에서,
scala> def even: Int => Boolean = { _% 2 == 0 } even: Int => Boolean scala> val even: Int => Boolean = { _% 2 == 0 } even: Int => Boolean = $$Lambda$1157/1017502292@57a0aeb8
데프 통화 별 이름 수요 평가를 의미합니다
발을 유도함으로써 값 초기화 동안 평가 수단
from https://stackoverflow.com/questions/18887264/what-is-the-difference-between-def-and-val-to-define-a-function by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라의 동반자 객체를 가진 뒤에있는 근거는 무엇입니까? (0) | 2019.10.31 |
---|---|
[SCALA] 어디는 "*** 그이야 flatmap"않습니다 스칼라의 관용적 표현에서 온? (0) | 2019.10.31 |
[SCALA] 어떻게 스파크 SQL DataFrame에서 열 유형을 변경하려면? (0) | 2019.10.31 |
[SCALA] 스칼라에서 암시 적 이해 (0) | 2019.10.31 |
[SCALA] 스칼라에서 ETA 확장은 무엇입니까? (0) | 2019.10.31 |