Julia Language
마감
수색…
통사론
- x -> [본문]
- (x, y) -> [본문]
- (xs ...) -> [본문]
비고
Julia의 이전 버전에서는 클로저와 익명 함수가 런타임 성능 저하를 겪었습니다. 이 벌은 0.5에서 제거되었습니다.
기능 구성
익명 함수 구문을 사용하여 함수 합성 을 수행하는 함수를 정의 할 수 있습니다.
f ∘ g = x -> f(g(x))
이 정의는 다음 정의와 각각 동일합니다.
∘(f, g) = x -> f(g(x))
또는
function ∘(f, g)
x -> f(g(x))
end
줄리아에서 f ∘ g
는 ∘(f, g)
대한 구문 설탕 일뿐입니다.
이 함수가 올바르게 구성되어 있음을 알 수 있습니다.
julia> double(x) = 2x
double (generic function with 1 method)
julia> triple(x) = 3x
triple (generic function with 1 method)
julia> const sextuple = double ∘ triple
(::#17) (generic function with 1 method)
julia> sextuple(1.5)
9.0
버전 v0.5에서는이 정의가 매우 효과적입니다. 생성 된 LLVM 코드를 살펴볼 수 있습니다.
julia> @code_llvm sextuple(1)
define i64 @"julia_#17_71238"(i64) #0 {
top:
%1 = mul i64 %0, 6
ret i64 %1
}
두 곱셈이 하나의 곱셈으로 접혀 졌음이 분명하며,이 함수는 가능한 한 효율적입니다.
이 고차 함수는 어떻게 작동합니까? 이것은 코드뿐만 아니라 범위에서 특정 변수를 추적하는 소위 폐쇄를 만듭니다. Julia에서 최상위 범위에서 작성되지 않은 모든 함수는 클로저입니다.
종결의 필드를 통해 닫힌 변수를 검사 할 수 있습니다. 예를 들어 다음과 같이 나타납니다.
julia> (sin ∘ cos).f
sin (generic function with 10 methods)
julia> (sin ∘ cos).g
cos (generic function with 10 methods)
Currying 구현하기
클로저의 한 응용 프로그램은 부분적으로 함수를 적용하는 것입니다. 즉, 이제 일부 인수를 제공하고 나머지 인수를 취하는 함수를 작성하십시오. currying 은 특정 형태의 부분 적용입니다.
먼저 함수에 첫 번째 인수를 제공하는 간단한 함수 curry(f, x)
부터 시작하여 나중에 추가 인수를 기대하십시오. 정의는 매우 간단합니다.
curry(f, x) = (xs...) -> f(x, xs...)
다시 한번 익명 함수 구문 을 사용합니다. 이번에는 가변 인수 구문과 함께 사용합니다.
이 curry
기능을 사용하여 묵시적 (또는 포인트 프리) 스타일로 몇 가지 기본 기능을 구현할 수 있습니다.
julia> const double = curry(*, 2)
(::#19) (generic function with 1 method)
julia> double(10)
20
julia> const simon_says = curry(println, "Simon: ")
(::#19) (generic function with 1 method)
julia> simon_says("How are you?")
Simon: How are you?
기능은 기대 한 generism를 유지한다 :
julia> simon_says("I have ", 3, " arguments.")
Simon: I have 3 arguments.
julia> double([1, 2, 3])
3-element Array{Int64,1}:
2
4
6
클로저 소개
기능 은 줄리아 프로그래밍의 중요한 부분입니다. 모듈 내에서 직접 정의 할 수 있으며이 경우 함수를 최상위 수준 이라고 합니다 . 그러나 함수는 다른 함수 내에서 정의 될 수도 있습니다. 이러한 기능을 " 폐쇄 (closure) "라고합니다.
클로저는 외부 함수에서 변수를 캡처합니다. 최상위 함수는 모듈, 함수 매개 변수 또는 지역 변수의 전역 변수 만 사용할 수 있습니다.
x = 0 # global
function toplevel(y)
println("x = ", x, " is a global variable")
println("y = ", y, " is a parameter")
z = 2
println("z = ", z, " is a local variable")
end
반면에 클로저는 캡처하는 외부 함수의 변수 외에 모든 함수를 사용할 수 있습니다.
x = 0 # global
function toplevel(y)
println("x = ", x, " is a global variable")
println("y = ", y, " is a parameter")
z = 2
println("z = ", z, " is a local variable")
function closure(v)
println("v = ", v, " is a parameter")
w = 3
println("w = ", w, " is a local variable")
println("x = ", x, " is a global variable")
println("y = ", y, " is a closed variable (a parameter of the outer function)")
println("z = ", z, " is a closed variable (a local of the outer function)")
end
end
c = toplevel(10)
을 실행하면 결과는 다음과 같습니다.
julia> c = toplevel(10)
x = 0 is a global variable
y = 10 is a parameter
z = 2 is a local variable
(::closure) (generic function with 1 method)
이 함수의 꼬리 표현은 그 자체로 하나의 함수라는 점에 유의하십시오. 즉 종결 자입니다. 우리는 폐쇄 호출 할 수 있습니다 c
이 다른 기능처럼 :
julia> c(11)
v = 11 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 10 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)
toplevel
이 이미 반환 되었더라도 여전히 c
는 toplevel
호출에서 변수 y
및 z
액세스 할 수 있습니다! 각 closure는 동일한 함수에 의해 반환되는 경우조차도 다른 변수를 통해 닫습니다. 다시 toplevel
호출 할 수 있습니다.
julia> d = toplevel(20)
x = 0 is a global variable
y = 20 is a parameter
z = 2 is a local variable
(::closure) (generic function with 1 method)
julia> d(22)
v = 22 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 20 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)
julia> c(22)
v = 22 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 10 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)
d
와 c
가 동일한 코드를 갖고 동일한 인수를 전달 받았음에도 불구하고 출력이 다릅니다. 그것들은 별개의 마개입니다.