본문 바로가기
Swift/기본

클로저 - @autoclosure

by 밤새는탐험가 2024. 3. 20.

클로저 - @autoclosure

파라미터로 전달된 일반 구문 또는 함수를 클로저로 래핑(Wrapping) 한다는 의미이다. 

 

즉, @autoclosure가 붙은 경우에는 일반 구문을 인자값으로 넣어도 컴파일러가 알아서 클로저로 만들어준다.

 

아래 코드는 클로저가 어떻게 판단을 지연하는지 보여준다.

클로저 내부의 코드에 의해 fruits 배열의 첫 번째 요소는 삭제 되지만, 

클로저가 실제로 호출되기 전까지 삭제되지 않습니다. 

 

var fruits: [String] = ["Apple", "Banana", "Kiwi", "Melon"]

let fruitsCheck = { fruits.removeFirst()}
print(fruits.count)   // 4

print("삭제 아이템: \(fruitsCheck())")  // 삭제 아이템: Apple
print(type(of: fruitsCheck))   // () -> String
print(fruits.count)   // 3

 

 

클로저는 선언 단계에서 바로 실행되지 않는다. 

호출이 되어야만 실행이 된다. 

fruitsCheck 타입은 String이 아니고 파라미터가 없고, 문자열을 반환하는 () -> String 이다. 

 

함수의 인수로 클로저를 전달하면 위와 같은 지연 판단과 동일한 동작을 할 수 있다. 

 

func runFunction(fruitsCheck: () -> String) {
    print("삭제 아이템: \(fruitsCheck())")
}

runFunction(fruitsCheck: { fruits.removeFirst()})
print(fruits.count)

 

runFunction(fruitsCheck:) 함수는 fruits 배열의 제거할 첫 번째 아이템을 반환한다.

 

아래에서 runFunction() 함수는 파라미터 타입에 "@autoclosure" 속성을 표기하여 자동 클로저를 가진다.

 

var fruits: [String] = ["Apple", "Banana", "Kiwi", "Melon"]

print(fruits.count)    // 4

func runFunction(fruitsCheck: @autoclosure() -> String) {
    print("삭제 아이템: \(fruitsCheck())")
}

runFunction(fruitsCheck: fruits.removeFirst())   // 삭제 아이템: Apple
print(fruits.count)   // 3

 

 

이제 클로저 대신 String 타입의 인수를 받는 것 처럼 함수를 호출 할 수 있다. 

 

// String 타입의 인수를 받는 것도 가능
runFunction(fruitsCheck: "사과")  // 삭제 아이템: 사과

 

 

⭐️ 클로저가 호출될 때까지 코드 내부 실행이 되지 않기 때문에 자동 클로저는 판단을 지연할 수 있다

⭐️ 인자값을 클로저 형태로 넣어줄 필요가 없기 때문에   "{ }" 형태가 아닌 "( )" 형태로 사용할 수 있다. 

⭐️ 너무 남발해서 사용하진 말자... 아직은 잘 모르겠다..

 

'Swift > 기본' 카테고리의 다른 글

함수  (0) 2024.03.22
컬렉션 타입  (0) 2024.03.21
기본 데이터 타입  (0) 2024.03.21
상수, 변수  (0) 2024.03.21
클로저  (0) 2024.03.20