Swift

@autoclosure

Phililip
728x90

안녕하세요.

 

이번에는 @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/

- https://medium.com/ios-os-x-development/https-medium-com-pavelgnatyuk-autoclosure-what-why-and-when-swift-641dba585ece

 

 


이번 글은 여기서 마무리.

 

 

 

반응형

'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