안녕하세요
오늘은 클로저를 알아봅시다!
클로저 뜻
우선 구글 번역기로
closure의 뜻을 알아보면
'폐쇄'
라고 나옵니다
변수에 함수가 갇혀있는 뜻이라고 생각하면 편할것 같습니다
타 언어 프로그래밍을
배우셨다면 클로저를 익명함수, 람다와 많이 유사한 부분이라고 느낄 수 있습니다
저또한 C#에서 많이 보던 녀석이라.. 낯설지 않았답니다
클로저는 정의된 모든 상수와 변수에 대한 참조를 캡처하고 저장이 가능합니다
이러한 상수와 변수를 Closing over이라고 합니다
제가 느낀바로는 함수와 클로저의 차이는
함수는
이름이 있는 코드의 묶음이여서 다른 코드에서 함수이름으로 호출하여 사용이 가능한 형태라고 생각이 들어요
클로저는
굳이 함수의 이름이 없어도 호출할 수 있는 형태라고 생각이 들어요
앞에서 배웠듯이
함수는 일급 객체로 취급이 되기 때문에
함수는 타입이다
|
함수를 변수에 할당할 수 있음
함수를 호출할 때 함수를 파라미터(매개변수)로 전달할 수 있음
함수에서 함수를 반환할 수 있음
우선 함수와 클로저의 기본형태를 보고 비교해 봅시다
함수와 클로저의 기본형태
//함수의 타입 표기
//input 문자열 / output 문자열
let functionA: (String) -> String
//input 정수 / output void (x)
let functionB: (Int) -> ()
//input 문자열 / output void (x)
let functionC: (String) -> Void
//함수의 타입 표기
//input 정수 / output void (x)
let function1: (Int) -> ()
//함수의 사용
func function2(name: String) -> String {
return "hello \(name)"
}
//function2를 클로저로 변환해보기
// _ : 와일드카드패턴(생략의 의미)
let _ = { (name: String) -> String in
return "hello \(name)" }
//아규먼트 레이블을 따로 사용하지 않음
let a = {(name: String) -> String in
return "hello \(name)"}
let aClosure = { () -> () in
print("hello")}
let aClosure1 = { print("hello")}
클로저 부분을 좀 더 자세히 본다면
여기서 알 수 있는 것은
클로저는 변수에 담을 수 있으며
축약 형식을 다양한 형태로 만들 수 있답니다
그리고 { } 중괄호를 열고 닫는다면 클로저가 있다고 생각을 해야합니다
그리고 유의할 점은 아규먼트 레이블 즉 파라미터 앞에 사용하는 별명같은 녀석은
사용하지 않습니다❌
그럼 변수에 담은걸 호출 할 수 있지 않을까?
네!
이렇게 소괄호를 사용하면 클로저 함수가 실행하게 됩니다
이렇게
hello joo
hello
hello
가 출력되는걸 확인할 수 있습니다
그리고 위에서 함수는 1급 객체에 대해서
클로저 예제를 보면서 설명하고자 합니다
둘 다 매개변수를 String type으로 받아서 String 타입으로 반환하고 있습니다
함수의 타입을
이렇게 나타낼 수 있습니다
클로저의 특징에 대해서 알아보고자 합니다
클로저 특징
클로저에 대한 타입추론이 가능하며
기본 자료형에 대한 타입추론 또한 가능한것을 볼 수 있습니다
예시로 하나 더 보자면
타입 추론이 가능하면 생략이 가능하고
return 타입도 생략을 할 수 있습니다
다음 특징으로는
클로저는 파라미터로 함수를 실행 할 수 있습니다
let start = { print(" s t a r t ") } // () -> () in 생략
let end = { print(" e n d ") } //() -> () in 생략
//소괄호가 없는건 가르키기만 하는것
//closure
func closureFunc(closure: () -> ()) {
print("hello")
closure() //class도 ()없으면 가르키는것 처럼 클로저도 동일함
}
//실제 클로저가 아닌 클로저 타입을 전달하고 있기 때문에 "hello"가 출력되지 않습니다
//"hello" 출력됨
closureFunc{ (() -> ()).self } //hello
print("⭐️exam⭐️")
closureFunc {
print("hi")
}
//hello
//hi
func printSwiftFunction() { // 함수를 정의
print("프린트 종료")
}
print("⭐️exam2⭐️")
closureFunc(closure: printSwiftFunction)
//hello
//프린트 종료
closureFunc {
print("이런식으로 많이 구현한다고함")
}
//hello
//이런식으로 많이 구현한다고함
클로저를 파라미터로 설정하는걸
보통 콜백함수라고 정의하고 있습니다
나중에 다시 호출하기 때문에 콜백함수라고 부르기도 하죠
콜백함수에 관한 활용에 관하여 알아보고자 합니다
//(Int) -> Void 에서 Void를 뜻함
//Void == () 동일하다
func closureCaseFunction(a: Int, b: Int, closure: (Int) -> Void) {
let c = a + b
closure(c)
}
//(Int) -> () 에서 ()를 뜻함
//Void == () 동일하다
func closureFunctionExam(a: Int, b: Int, closure: (Int) -> ()) {
let c = a + b
closure(c)
}
closureFunctionExam(a: 10, b: 10, closure: {param -> () in print("\(param)으로 출력됩니다")}) //20으로 출력됩니다
closureFunctionExam(a: 10, b: 10, closure: {num in print("\(num)으로 출력됩니다")})
closureFunctionExam(a: 10, b: 10) { num in
print("출력시작")
print("\(num)으로 출력됨")
print("출력종료")
}
// 2) 함수를 실행할 때 (클로저 형태로 전달)
closureCaseFunction(a: 5, b: 2, closure: { (n) in // 사후적 정의
print("이제 출력할께요: \(n)")
})
//소괄호를 땡겨주면 클로저가 사라짐
closureCaseFunction(a: 5, b: 2) {(number) in // 사후적 정의
print("출력할까요? \(number)")
}
closureCaseFunction(a: 5, b: 3) { (number) in // 사후적 정의
print("출력")
print("출력")
print("출력")
print("값: \(number)")
}
closureCaseFunction(a: 3, b: 4, closure: { number in print("number is \(number)")})
이렇게 순서도 정할 수 있답니다
그럼 콜백함수를 파라미터로 여러개 넣어서 사용할 수도 있겠구나 활용도 생각할 수 있다면
아주 좋답니다
+
이렇게 선언하게되면
input(Void) -> output(String)
타입 추론이 가능합니다
이 경우에는
input과 output 동일하게
void 타입 추론을 하고있는것을 알 수 있습니다
❤️혹시나 잘못된 부분이 있다면 댓글로 알려주면 감사하겠습니다❤️
✏️참고
앨런스위프트 문법 자료(강의)⭐️⭐️⭐️ -추천
꼼꼼한 재은씨의 스위프트 프로그래밍
Swift 공식문서
구글번역기
'Swift' 카테고리의 다른 글
Swift | ARC에 관하여[WWDC21] (1) | 2024.05.22 |
---|---|
Swift | 클로저(Closure)에 관하여 -2 (0) | 2024.05.21 |
Swift | self vs Selft에 관하여 (0) | 2024.05.21 |
Swift | Method Dispatch관하여 (0) | 2024.05.21 |
Swift | 고차함수 filter / reduce 관하여 (0) | 2024.05.21 |