2025.03.19 - [IT/프로그래밍 노트] - 010 Closure 클로저
010 Closure 클로저
자동목차 📌 1️⃣ 함수와 클로저의 관계함수가 반복적으로 사용할 수 있는 코드 블록을 뜻하는 거면 클로저는 코드블록을 다른 곳으로 전달하는데에 집중 (파라미터로 코드블록을 전달)
margot33-0.tistory.com
클로저의 기본 형태
{ (매개변수) -> 반환타입 in
실행할 코드
}
클로저의 기본 문법 형태는 이렇게 매개변수와 리턴 화살표, 리턴타입 , in 키워드, 실행할 코드로 이루어져 있다.
하지만 이 형태는 종종 { 실행할코드 } 라는 형태로만 보이기도 하다.
코드를 생략가능한 부분은 지우고 최대한 깔끔한 형태로 변경가능하다고 하다.
클로저 단축 방법
✔️ 파라미터 타입, 리턴타입 생략 가능
Swift에서는 타입추론이 가능하기 때문에 파라미터 타입과 반환타입이 명확하면 생략 가능.
✔️ 파라미터 이름, in 키워드도 생략 가능
파라미터 이름이 클로저 바디에 쓰이면 컴파일러가 파라미터를 추론 가능, 파라미터 이름 삭제 및 in 키워드 삭제 가능.
파라미터 이름이 클로저 바디에 쓰이지 않으면 컴파일러가 파라미터 추론 불가능, 파라미터가 없다고 추론, 삭제 X _ 언더스코어로 생략은 가능하지만 이 경우 in 키워드 생략 불가능
✔️ 파라미터 이름 생략시 해당 이름은 클로저 바디에서 사용 불가능, Shorthand Argument Name ($n)을 사용
✔️ 클로저 바디를 봤을 때 return문이 1개 밖에 없으면 return키워드 생략 가능
다른 키워드가 포함되어 있으면 생략 불가능
✔️ implicit return 클로저바디의 코드가 짧을 때 줄바꿈하지 않고 1줄로 쓰기
✔️ 클로저 1개가 유일한 동시에 마지막 파라미터면 inline closure(괄호 안에 있는 클로저)를 trailing closure(괄호 뒤 클로저)로 바꿀 수 있고 괄호는 비어 있을 경우 생략 가능
클로저 단축 예제 1
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var result = arr.filter({ (num: Int) -> Bool in
return num.isMultiple(of: 2)
})
print(result)
// 파라미터 타입, 리턴타입 생략
result = arr.filter({ (num) in
return num.isMultiple(of: 2)
})
print(result)
// 파라미터 이름 , in 키워드 생략
// 파라미터 이름 대신 Shorthand Argumentname $0 사용
result = arr.filter({
return $0.isMultiple(of: 2) // short - hand argument name $n
})
print(result)
// return 키워드 생략, implicit return
result = arr.filter({ $0.isMultiple(of: 2)}) // implicit return
print(result) // inline closure
// inline closure를 trailing closure로 변경, ()생략
result = arr.filter { $0.isMultiple(of: 2) }
print(result)
shorthand argument name , $n
Swift에서 shorthand argument name은 클로저(Closure)에서 매개변수를 간편하게 참조할 수 있도록 제공하는 기능이다. 보통 클로저에서 매개변수를 명시적으로 선언하지 않고도 $0, $1, $2 같은 형태로 인덱스를 사용해 접근할 수 있다.
📌 기본 문법
- $0: 첫 번째 매개변수
- $1: 두 번째 매개변수
- $2: 세 번째 매개변수
(이후는 매개변수 순서에 따라 계속 증가)
✅ 예제 1: 기본 클로저와 shorthand argument 비교
// 일반적인 클로저 사용
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { (num: Int) in
return num * 2
}
print(doubled) // [2, 4, 6, 8, 10]
// shorthand argument 사용
let doubled2 = numbers.map { $0 * 2 }
print(doubled2)
// [2, 4, 6, 8, 10]
💡 차이점
- 일반 클로저: num이라는 매개변수를 선언하고 사용.
- shorthand argument: in 키워드 없이 $0으로 첫 번째 매개변수를 바로 사용.
✅ 예제 2: 정렬에 활용
let names = ["Kim", "Lee", "Park", "Choi"]
// 이름을 내림차순으로 정렬
let sortedNames = names.sorted { $0 > $1 }
print(sortedNames) // ["Park", "Lee", "Kim", "Choi"]
여기서 $0은 첫 번째 요소, $1은 두 번째 요소를 나타냄.
✅ 예제 3: 필터링에 활용
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // [2, 4]
$0은 배열의 각 요소를 나타내며, 짝수만 필터링함.
📊 shorthand argument 사용 시 주의점
- 가독성 문제: 너무 많으면 코드가 복잡해져서 읽기 어려울 수 있음.
- 복잡한 로직: 매개변수가 많거나 로직이 복잡하면 명시적인 이름을 사용하는 것이 좋음.
- 순서 혼동: $0, $1의 순서를 헷갈리지 않도록 주의.
📌 정리
- 간단한 로직에는 shorthand argument를 쓰면 코드가 깔끔하고 짧아짐.
- 복잡한 로직에는 명시적 매개변수를 쓰는 것이 좋음.
- 주로 **map, filter, sorted, reduce**와 같은 고차 함수에서 사용.
클로저 단축 예제2
let action = UIAlertAction(title: "+ (더하기)", style: .default, handler: { (action: UIAlertAction) -> Void in
self.operatorButton.setTitle("+", for: .normal)
})
// 파라미터 타입, 리턴 타입 생략
let action = UIAlertAction(title: "+ (더하기)", style: .default, handler: { (action) in
self.operatorButton.setTitle("+", for: .normal)
})
/*
파라미터 이름 언더스코어로 생략 (in 키워드가 생략 불가 하기 때문에 언더스코어로 생략 , 그냥 삭제하면 안됨)
클로저바디에 있는 코드를 보면 action 파라미터를 사용하지 않고 있기 때문에 파라미터 이름을 그냥 지우게 되면
컴파일러가 파라미터가 없다고 인식하기 때문에 삭제 X, 언더스코어로 생략, 그리고 파라미터를 지우지 않았기 때문에
in 키워드도 생략불가
*/
let action = UIAlertAction(title: "+ (더하기)", style: .default, handler: { _ in
self.operatorButton.setTitle("+", for: .normal)
})
// inline closure 가 마지막에 적혀 있으니 trailing closure로 변경 가능, () 삭제는 불가능
let action = UIAlertAction(title: "+ (더하기)", style: .default, handler: ) { _ in
self.operatorButton.setTitle("+", for: .normal)
}
// UIAlertAction 내 마지막 파라미터인 handler 생략
let action = UIAlertAction(title: "+ (더하기)", style: .default) { _ in
self.operatorButton.setTitle("+", for: .normal)
}
클로저 의 in 키워드는 매개변수와 실행할 코드를 구분지어주는 키워드이다.
이 키워드를 통해 Swift 컴파일러는 어디까지가 매개변수 선언이고 어디서부터 실행코드인지 판별하게 된다.
이걸 매번 단축 과정을 거쳐서 줄이는게 아니라 처음 입력할 때부터 이게 머릿속에 있어서
바로 단축완료된 코드로 나와야한다니..?
띠로리..
'IT > Swift 노트' 카테고리의 다른 글
013 함수표기법 (0) | 2025.03.23 |
---|---|
030 Navigation Bar, Segue (0) | 2025.03.23 |
029 TextFieldDelegate 숫자 입력 검증, guard문 (0) | 2025.03.20 |
011 Function Type, Closure Type, 함수자료형, 클로저 자료형 (0) | 2025.03.19 |
010 Closure 클로저 (0) | 2025.03.19 |