일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 패캠강의후기
- 패캠
- fastcampus
- 코딩교육
- reactnative강의
- 패캠챌린지
- 자바스크립트
- 패캠reactnative
- 자바
- 패캠인강후기
- 코딩테스트
- 패스트캠퍼스후기
- 수강료0원챌린지
- 직장인인강
- 파이썬
- 오공완
- 30개프로젝트로배우는iOS앱개발withSwift초격차패키지Online.
- 직장인공부
- 직정인자기계발
- 패스트캠퍼스
- 직장인자기계발
- 환급챌린지
- 코딩자격증
- Today
- Total
라티의 작은 일기장
[11일차] 클로저 본문
오늘은 내가 4학년으로 올라가는... 개강일이었다. 시장통을 방불케하는 시끌벅적한 캠퍼스가 적응이 되지 않았지만... ㅠㅠ
이러나 저러나 오늘도 Swift 공부는 미룰 수 없다!
오늘은 클로저(Closure)에 대해 공부해보려고 한다.
클로저?
클로저를 처음 들어보는 사람도 있겠지만, JS(JavaScript)를 공부해 본 사람들은 이미 알고 있는 개념일 것이다.
JS에서는 익명 함수 등으로 소개되어 있을 수도 있다.
음... 일단, 클로저는 코드에서 전달하거나 사용할 수 있는 독립 기능 블록이며, 일급 객체의 역할을 수행한다.
여기서 일급 객체는 파라미터로 보낼 수도 있고, 변수 / 상수의 값으로 저장하거나 함수의 반환 값이 될 수 있는 객체이다.
그렇다고 이게 JS의 기능인가? 그렇지는 않다. 클로저의 개념은 원래 존재했고, JS에 기능으로 구현한 것이기 때문이다.
그래서 Swift에서 클로저는 JS의 클로저와 기능이 같다.
Swift에서 클로저 표현식을 살펴보자.
{ (매개변수) -> 리턴 타입 in
실행 구문
}
여기서 (매개변수) -> 리턴 타입을 클로저 헤드, 실행 구문을 클로저 바디라고 한다. 이 둘을 구분 짓는 키워드가 in인 것이다.
클로저의 기본 예시를 코드로 살펴보자.
let hello = { () -> () in
print("Hello!")
}
hello()
let hello2 = { (name: String) -> String in
return "Hello, \(name)"
}
hello2("Rati")
hello에 할당된 클로저는 파라미터와 리턴값이 없는 클로저, hello2에 할당된 클로저는 파라미터와 리턴값이 있는 클로저이다.
실행 결과를 보면 다음과 같다.
여기서 주의 깊게 볼 부분은, 클로저에 파라미터를 넘길 때 레이블을 사용하지 않는다는 것이다. 사용하면 에러가 난다.
또한 클로저는 일급 객체로서, 파라미터로 전달되거나 반환값으로 반환 될 수도 있다고 했는데, 그에 대한 예시를 살펴보자.
func doSomething(closure: () -> ()) {
closure()
}
doSomething(closure: { () -> () in
print("Hello~")
})
doSomething 함수는 클로저를 전달받아 클로저를 호출하는 함수이다.
함수를 선언하고 Hello~ 문자열을 출력하는 print문을 반환하는 클로저를 파라미터로 전달하였다.
실행 결과는 다음과 같다.
클로저를 반환하는 코드의 예시도 살펴보자.
func doSomething2() -> () -> () {
return { () -> () in
print("Hello#")
}
}
doSomething2()()
천천히 살펴보자. doSomething2 함수는 일단 클로저를 반환하는 클로저를 반환 타입으로 갖고 있고,
반환하는 클로저가 반환하는 클로저는 아무런 파라미터를 받지 않으면서 Hello# 문자열을 출력하는 print문을 실행한다.
말이 좀 어렵긴 한데.. 긴 영어 문장 나눠서 해석하는 것 처럼 호출 및 반환 관계를 생각하면서 보면 된다. 사실 나도 잘 이해한건지 모르겠다.
그래서 일단 클로저가 두 개니까 소괄호 쌍도 두 개로 적고, 실행 결과 print문이 잘 실행되는 것으로 이해했다.
다음은 클로저의 가독성을 향상시키기 위한, 후행 클로저를 사용하는 방법에 대해 알아보자.
func doSomething(closure: () -> ()) {
closure()
}
doSomething(closure: { () -> () in
print("Hello~")
})
doSomething() {
print("Hello@")
}
클로저를 받아서 클로저를 호출해주는 doSomething 함수와, 클로저를 넘겨주는 코드를 가져와서 간소화를 해보겠다.
우선 클로저가 파라미터도 받지 않고 리턴도 하지 않는데 실행 구문이 있으면 저렇게 죄다 생략을 할 수 있다.
확인해보니 똑같은 기능을 수행하는데 아랫쪽 클로저가 훨씬 간단하다.
클로저가 여러개인 경우도 간소화가 가능하다.
func doSomething2(success: () -> (), fail: () -> ()) {
}
doSomething2 {
<#code#>
} fail: {
<#code#>
}
또 이런 식의 간소화도 가능하다.
func doSomething3(closure: (Int, Int, Int) -> Int) {
closure(1,2,3)
}
doSomething3(closure: {(a, b, c) in
return a+b+c
})
doSomething3(closure: {
return $0+$1+$2
})
doSomething3(closure: {
$0+$1+$2
})
doSomething3() {
$0+$1+$2
}
doSomething3 {
$0+$1+$2
}
doSomething3 호출문이라고 작성한 것들은 모두 같은 기능을 수행하는 코드이다 놀랍게도...
단, 여기서 return 키워드를 생략하는 단계가 있는데, return문 이외에 다른 실행문이 있으면 return 키워드를 생략할 수 없다.
Swift에서 클로저에 대해 알아보았다. JS도 어려웠지만 Swift도 만만치 않다.. 잘 써먹을 수 있길!!
패스트캠퍼스 바로가기 : http://bit.ly/3Y34pE0
> 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
'Swift' 카테고리의 다른 글
[13일차] [명언 생성기 앱] AutoLayout (0) | 2023.03.04 |
---|---|
[12일차] [명언 생성기 앱] UIKit & UIViewController (0) | 2023.03.03 |
[10일차] try-catch (0) | 2023.03.01 |
[9일차] 익스텐션, 열거형, 옵셔널 체이닝 (0) | 2023.02.28 |
[8일차] 프로토콜 (0) | 2023.02.27 |