Swift 문법종합 - 클로저

동그라미·2024년 11월 11일
4

10-1. 클로저

[코드스니펫] 클로저 구현 코드

let closure: (Int, String) -> Void = { intValue, stringValue in 
								// in 키워드를 사용하여 앞에는 파라미터 이름을 뒤에는 구현부를 작성합니다.
    print(intValue)
    print(stringValue)
}
// ⬆️ 오랜만에 한국말로 읽어보기! 
// closure 상수의 타입은 클로저로 Int, String 타입의 파라미터가 있고 Return은 없습니다.
// 할당값은 클로저의 구현입니다.

// 파라미터의 이름을 생략하면 구현부에서 $0로 사용할 수 있습니다.
// 파라미터의 이름을 생략했기 때문에 in 키워드도 생략합니다. 
let closure2: (Int) -> Void = { 
    print($0)
}

let closure3: () -> Void = {
    print("Hello")
}

// 파라미터의 이름을 value라고 사용하고 Int값을 리턴합니다.
let closure4: (Int) -> Int = { value in
    return value * 2
}

let closure5: (String, Int) -> Int = {
    return $0.count + $1
}

let optionalClosure: ((Int) -> Int)? = { value in
    return value * 2
}

// 파라미터가 없을 때는 in을 사용하면 안됩니다. 
let emptyParameterClosure: () -> Void = {
	print("World")
}

  • 익명 함수 라고 불리는 클로저는 함수와 유사하게 특정 작업을 수행하는 코드블록 입니다.
  • 함수의 4가지 요소(이름, 파라미터, 반환타입, 구현부)에서 이름 을 제외한 파라미터, 반환타입, 구현부 로 구성되어 있습니다.
  • 데이터타입으로 클로저를 사용할 수 있습니다.
    • 변수에 할당하여 재사용할 수 있습니다.
    • 함수의 파라미터로 전달할 수 있습니다.
  • 클로저가 함수 안에 포함된 것이 아니라 클로저 안에 함수가 포함되어 있습니다.

  • 코드의 재사용성을 높이고, 비동기 처리, 컬렉션 연산 등의 장점이 있습니다.

// 타입으로 사용할 때 표현방법
(파라미터 데이터 타입) -> 리턴 타입 
  • 파라미터의 타입은 없을 때 비워두고, 리턴 타입이 없는경우 Void 라고 명시합니다.

  • 파라미터가 없을때도 () 괄호는 있어야 합니다!

  • 데이터 타입으로 사용할 수 있기 때문에 Optional 타입으로 사용할 수 있습니다.
    이 때 전체를 () 로 감싼 후 ? 를 입력해야 합니다.

let closure: (Int, String) -> Void // 파라미터는 튜플(Int, String) 타입이고
																	 // 반환타입은 없습니다.
																	 // 만약 -> Void가 생략되었다면 튜플과 같죠!?

let closure2: (Int) -> Void        // 파라미터는 1개로 Int이며 반환타입은 없습니다.

let closure3: () -> Void           // 파라미터는 없고 반환타입은 없습니다.
																	 // 파라미터는 ()로 감싸고 있어서 Void를 생략할 수 있어요.

let closure4: (Int) -> Int         // 파라미터는 1개이고 Int 타입이며, 반환값은 Int 입니다. 
let closure5: (String, Int) -> Int // 파라미터는 튜플(String, Int) 타입이고
																	 // 반환타입은 Int 입니다.

let optionalClosure: ((Int) -> Int)? // 옵셔널 타입입니다.
																		 // 만약 ()가 없었다면 리턴값이 Int? 라고 판단됩니다!

클로저 구현하는 방법

  • 클로저는 익명함수 이므로, 구현할 때 in 키워드를 사용하여 파라미터와 구현부를 구분해야 합니다.
// 기본적인 구현 방법
// 중괄호로 시작하고 파라미터와 구현부 부분을** in ** 키워드를 사용하여 나눕니다.
{ 파라미터 이름 in  
	// 구현부
	// 리턴
}
  • in 키워드를 사용하여 앞에는 파라미터 이름을 뒤에는 구현부를 분리하여 작성합니다.
  • 파라미터 이름은 생략 가능하며 0번째 파라미터 $0 으로 사용할 수 있습니다. ($0, $1, $2 …) 파라미터 이름을 생략할 때는 in 키워드까지 생략해야 합니다.
  • 파라미터가 없다면 in 을 생략해야 합니다.
  • 파라미터 이름은 사용하실 이름을 자유롭게 작성하면 됩니다.

[코드스니펫] 클로저 구현 코드

let closure: (Int, String) -> Void = { intValue, stringValue in 
								// in 키워드를 사용하여 앞에는 파라미터 이름을, 뒤에는 구현부를 작성합니다.
    print(intValue)
    print(stringValue)
}
// ⬆️ 오랜만에 한국말로 읽어보기! 
// closure 상수의 타입은 클로저로 Int, String 타입의 파라미터가 있고 Return은 없습니다.
// 할당값은 클로저의 구현입니다.

// 파라미터의 이름을 생략하면 구현부에서 $0로 사용할 수 있습니다.
// 파라미터의 이름을 생략했기 때문에 in 키워드도 생략합니다. 
let closure2: (Int) -> Void = { 
    print($0)
}

let closure3: () -> Void = {
    print("Hello")
}

// 파라미터의 이름을 value라고 사용하고 Int값을 리턴합니다.
let closure4: (Int) -> Int = { value in
    return value * 2
}

let closure5: (String, Int) -> Int = {
    return $0.count + $1
}

let optionalClosure: ((Int) -> Int)? = { value in
    return value * 2
}

// 파라미터가 없을 때는 in을 사용하면 안됩니다. 
let emptyParameterClosure: () -> Void = {
	print("World")
}

클로저를 사용(호출)하는 방법

  • 클로저를 변수나 상수에 저장했다면 함수처럼 이름뒤에 괄호를 사용하면 됩니다.
  • 옵셔널 변수에 저장한 클로저는 변수이름?() 형식으로 사용하면 됩니다.
  • 구현하고 즉시 호출한 결과값을 저장하고 싶다면 {} 뒤에 괄호() 를 사용하면 됩니다.

// 변수에 저장한 클로저 호출
let closure: (Int, String) -> Void = { intValue, stringValue in
    print(intValue)
    print(stringValue)
}

closure(10, "20")

/* 출력 값
10
20
*/

// 옵셔널 변수에 저장한 클로저 호출

let optionalClosure: ((Int) -> Int)? = { 
    return $0 * 2
}

print(optionalClosure?(10)) // 옵셔널 상수 optionalClosure의 클로저를 호출합니다.
													  // 상수의 타입이 optional이기 때문에 결과값이 Optional로 나옵니다.

/* 출력 값
Optional(20)
*/

// 옵셔널 변수에 저장한 클로저 호출

let optionalClosure: ((Int) -> Int)? = { 
    return $0 * 2
}

print(optionalClosure?(10)) // 옵셔널 상수 optionalClosure의 클로저를 호출합니다.
													  // 상수의 타입이 optional이기 때문에 결과값이 Optional로 나옵니다.

/* 출력 값
Optional(20)
*/

// 구현하고 바로 호출

// 클로저를 구현하고 바로 실행하여 결과값을 helloClosure 상수에 할당합니다.
let helloClosure = {
    return "안녕하세요! 구현하자마자 바로 실행해보겠습니다!"
}()

print(helloClosure) // 안녕하세요! 구현하자마자 바로 실행해보겠습니다!


profile
맨날 최선을 다하지는 마러라. 피곤해서 못산다.

0개의 댓글