안녕하세요.
이번에는 @autoclosure라는 속성에 대해 알아볼게요.
# @autoclosure
@autoclosure는 쉽게 말해서 함수 인자(argument)로 전달되는 expression(저는 단순 값이라고 이해했어요.)을 자동으로 함수 안에서 클로저 형태로 사용할 수 있게 해주는 속성입니다.
(이때 만들어진 클로저 자체에 대한 argument는 없습니다.)
반대로 말하면, 단순 리턴값만 존재하는 클로저를 함수 인자로 전달해야 할 때 @autoclosure를 사용하면 클로저 형태가 아닌 값 자체를 함수 인자로 넘길 수 있다는 얘기가 됩니다.
어떤 말인가 하면,
아래 같은 예시가 있다고 해볼게요.
serve(customer:) 함수의 customerProvider 타입은 String이 아니라 () -> String 클로저 입니다.
그래서 인자로 customersInLine.remove(at:0)이 아닌 { customersInLine.remove(at:0) } 를 넘긴 것이에요.
이번에는 @autoclosure를 사용한 예시를 한번 보여드릴게요.
@autoclosure를 사용하면 일부러 중괄호를 사용해서 클로저를 만들 필요 없이 클로저의 리턴값 자체를 넘기고, 함수 안에서는 클로저처럼 사용할 수 있게 됩니다.
(결론적으로는, 두 예시 모두 같은 동작을 하는 것이죠.)
여기서 한 가지 의문이 듭니다.
그래서...... 끝이야.....?
네. 끝입니다.
다만, 주의할 점이 있어요.
@autoclosure 함수 인자로 넘긴 expression은 함수 내부에서 클로저를 호출할 때 비로소 동작한다는 사실을 꼭꼭 기억해야 합니다.
한 가지 예시를 보여드릴게요.
serve1(customer:) 함수는 단순히 String 타입을 인자로 받는 함수이고, serve2(customer:) 함수는 @autoclosure 속성을 사용한 함수입니다.
serve1 함수를 호출할 때는 customersInLine.remove(at: 0)를 먼저 동작시키고 그 결과값("Chris")을 함수 인자로 넘기기 때문에 함수 안에서 배열 개수를 출력하게 되면 5개에서 1개가 적어진 4가 출력됩니다.
하지만 serve2 함수를 호출할 때는 함수 내부에서 customerProvider 클로저를 호출할 때 그제야 customersInLine.remove(at: 0)가 동작이 하기 때문에, 클로저가 호출되기 전에 배열 개수를 출력하면 3이 아니라 그대로 4를 출력하는 것이죠.
이해가 좀 되시나요???ㅎㅎㅎ
이처럼 @autoclosure 사용 여부에 따라서 함수 호출 코드는 완전히 동일하지만 결과값은 다를 수 있기 때문에 @autoclosure를 남용하는 것은 지양하고 있는 점 주의해야 합니다.
# @escaping 속성도 같이 쓸 수 있답니다.
결국 @autoclosure 속성을 받은 매개변수(parameter)는 클로저이기 때문에 @escaping 속성도 같이 사용 가능합니다ㅎㅎ
# 참고
- https://docs.swift.org/swift-book/LanguageGuide/Closures.html
- https://www.swiftbysundell.com/articles/using-autoclosure-when-designing-swift-apis/
이번 글은 여기서 마무리.
'Swift' 카테고리의 다른 글
computed property vs method (0) | 2023.01.13 |
---|---|
mutating (1) | 2022.12.18 |
Optional에서의 map, flatMap (0) | 2022.09.04 |
@inlinable, @usableFromInline (0) | 2022.08.15 |
[Swift 5.7] if let shorthand (0) | 2022.07.05 |