Closure (1)

9945 단어 swiftswift

swift 언어에서 optional만큼 중요한 closure에 대해서 알아보자.

Closure

Closure = 익명함수 라고 생각할 수 있지만 사실 closure는 func 키워드를 사용해서 이름을 붙여주는 함수들 모두를 클로저라고 할 수 있다.

즉, 클로저에는 Named Closure와 Unnamed Closure가 있는데 우리가 익숙하게 보았던

func doSomething() {
	print("소연")
}

이와 같은 이름이 있는 함수는 Named Closure라고 할 수 있다. 단지 이를 통상적으로 클로저라고 하지 않고 그냥 함수라고 부르는 것이다. (하지만 클로저라는 사실은 변함이 없다.)

let closure = { print("소연") }

위와 같이 이름을 붙이지 않고 사용하는 함수를 Unnamed Closure, 익명 함수라고 부르고 보통 클로저라고 하면 이것을 칭하는 용어이다.

클로저는 Named Closure 와 Unnamed Closure 둘 다 포함하지만 보통 Unnamed Closure를 말한다.

그리고 클로저 역시 익명인 함수이므로 swift 언어의 함수가 가지고 있는 특징인 1급 객체 함수의 특징을 갖고 있다.

  • 변수, 상수에 대입할 수 있고
  • 반환 값으로 사용할 수 있고
  • 인자 값으로 전달 할 수 있다.
    따라서 클로저 또한 자료형을 갖고 있다.

Closure 표현식

보통 클로저의 경우

{
	(Parameters) -> Return Type in	
    실행 구문
}

이렇게 쓰고 익명 함수이기 때문에 func 이라는 키워드를 사용하지 않는다.


위에서 볼 수 있는 것처럼 클로저 헤드와 클로저 바디로 구성되어 있고 헤드와 바디를 이어주는 것이 in 키워드이다.

Parameter와 Return Type이 둘 다 없는 클로저

클로저는 익명 함수이고 swift에서 함수는 일급 객체이기 때문에 상수에 클로저를 대입할 수 있다.
그리고 Parameter와 Return Type이 없는 경우는 다음과 같이 사용할 수 있다.

let closure = { () -> () in
    print("Closure")
}

클로저의 특징은 Return Type이 있어도 생략 가능하고 함수에서는 안되는 Parameter 조차 생략할 수 있다.

Parameter와 Return Type이 있는 클로저

let closure = { (name: String) -> String in
    return "Hello, \(name)"
}

여기서 주의할 점은 함수처럼 Parameter의 'name'이 단독으로 쓰였으니 argument label이자 parameter name이라고 생각할 수 있지만, 클로저에서는 argument label을 사용하지 않는다.

그렇기 때문에 위와 같이 선언한 클로저에 대해서

closure("소연")
closure(name: "소연")  //error!

argument label을 사용하면 에러가 날 수 있다.

일급 객체로써의 클로저

클로저는 함수, swift에서 함수는 일급 객체, 그러므로 클로저는 일급 객체이다.

클로저를 변수/상수에 대입할 수 있다.

클로저를 변수,상수에 대입 가능하며 이 대입된 변수, 상수로 실행할 수 있다.

let closure = { () -> () in
    print("Closure")
}

let closure2 = closure

대입과 동시에 클로저를 작성할 수도 있고 클로저를 대입한 변수,상수를 새로운 변수,상수에 대입할 수 있다.

함수의 인자로 클로저를 전달할 수 있다.

swift에서 함수는 인자로 전달 될 수 있고

func doSomething(closure: () -> ()) {
    closure()
}

그 특징을 이용해서 위와 같이 함수를 파라미터로 전달 받는 함수를 만들었을 때

doSomething(closure: { () -> () in
    print("Hello!")
})

이렇게 클로저를 전달해도 된다.


초록색 영역이 클로저로 작성된 부분을 말하고 이것이 함수의 파라미터로 전달된 것이다. 해당 함수를 실행하면 Hello!가 콘솔에 나타난다.

함수의 반환 타입으로 클로저를 사용할 수 있다.

func doSomething() -> () -> () {
	return { () -> () in
        print("Hello!")
    }
}

위와 같이 실제 값을 return 할 때 함수가 아닌 클로저를 리턴할 수 있다.

let closure = doSomething()
closure()

그리고 호출하는 곳에서 클로저를 받아 위와 같이 실행할 수 있다.

Closure 실행

클로저를 실행할 수 있는 방법은 크게 두가지가 있다.

클로저가 대입된 변수나 상수로 호출하기

let closure = { () -> String in
    return "so yeon"
}

closure()

클로저가 대입된 상수 closure를 호출 구문()을 통해서 실행할 수 있다.

클로저 직접 실행하기

만약 변수, 상수에 대입하지 않고 실행시키고 싶다면(= 일회성 함수) 클로저를 소괄호로 감싸고 마지막에 호출 구문()를 추가하면 된다.

({ () -> () in
    print("so yeon")
})()

두가지 경우 모두 so yeon이 출력 된다.

좋은 웹페이지 즐겨찾기