이 글은 스위프트 공식 블로그의 Swift 5.2 Released! 글에서 언급한 두 가지 업데이트된 기능을 살펴보는 글입니다. 이 외에도 사실 여러 업데이트가 있겠지만 아무래도 이게 핵심이니까 언급한 것이겠죠?
키 경로 표현식을 함수처럼 사용하기
SE-0249 Key Path Expressions as Functions 제안을 통해 Swift 5.2에 구현된 기능입니다.
이 기능은 함수나 클로져를 넘겨서 처리하는 다양한 기능에서 함수나 클로져 대신 키 경로(Key Path)를 넘기는 것으로 구현을 간단하게 할 수 있도록 해줍니다. 간단하게 위의 제안 내용의 예제를 인용해 보겠습니다.
우선 아래의 구조체 User
를 선언했습니다.
struct User {
let email: String
let isAdmin: Bool
}
이걸 이용해 데이터를 생성해 볼게요.
let users: [User] = [
User(email: "sam@foo.com", isAdmin: false),
User(email: "jack@foo.com", isAdmin: true),
User(email: "james@bar.com", isAdmin: false)
]
만약 여기서 email
의 내용만 따로 추출해 내려고 할 때 우리는 지금까지 아래와 같은 코드를 사용할 수 있었습니다.
users.map { $0.email } // 1번 예제
// => ["sam@foo.com", "jack@foo.com", "james@bar.com"]
그런데 Swift 5.2부터는 아래와 같은 식으로 좀 더 단순화시킬 수 있습니다.
users.map(\.email) // 2번 예제
// => ["sam@foo.com", "jack@foo.com", "james@bar.com"]
1번 예제에서는 map
을 호출할 때 표현식으로 (User) -> String
타입의 클로저가 사용되었습니다. 그런데 이 (User) -> String
클로져 구현을 2번 예제에서는 간단히 \.email
만으로 끝내버릴 수 있게 된 것이네요.
위 예제를 좀 다르게 표현하면 아래와 같습니다.
let f: (User) -> String = \.email
users.map(f)
// => ["sam@foo.com", "jack@foo.com", "james@bar.com"]
f
는 (User) -> String
타입의 클로저 타입인데 여기다 그냥 \.email
이라는 키 경로를 대입했는데 이게 된다는 겁니다 글쎄. 와 신기해라.
위 제안 내용에는 이보다 더 다양한 표현 방법을 소개하고 있습니다만 일부는 되지 않는 경우도 있어서 일단 제외했습니다. 아무래도 Xcode 11.4가 Swift 5.2의 첫 버전이니 오류가 있을 가능성도 있지요. (아니면 제 이해가 부족하거나😭)
솔직히 소감은 잘... 모르겠네요. 가독성이 많이 좋아지는 것도 아니고 코드도 살짝 짧아진 정도입니다. 하지만 이런 기능을 굳이 구현한 이유는 아마도 다른 기능 구현에서 좀 더 편리함을 주려는 요소가 아닐지 생각됩니다. Property Wrapper도 SwiftUI를 위한 큰 그림이었던 것처럼 말이죠.
자신을 호출시킬 수 있는 타입
제목을 짓는데 상당히 난감한 SE-0253 Callable values of user-defined nominal types 제안을 통해 Swift 5.2에 구현된 기능입니다.
일단 값이라고 적긴 했는데 struct든 class든 다 되는 기능입니다. 핵심은 callAsFunction
이라는 특수한 메서드를 구현할 수 있게 되었다는 점입니다. 이 메서드는 해당 인스턴스가 직접 호출될 때 호출되는 메서드입니다.
이해가 안 될 것 같으니 다짜고짜 예제로 넘어갑니다. 아래의 구조체를 하나 만들었습니다.
struct Grower {
var value = 1
}
아직까진 별거 없습니다. 여기에 callAsFunction
을 하나 붙여볼게요.
struct Grower {
var value: Int = 1
mutating func callAsFunction() -> Int {
value = value * 2
return value
}
}
callAsFunction
은 value
프로퍼티를 2배로 늘리고 이 값을 리턴하는 메서드입니다.
이것만 봐도 감이 안 온다면 이어서 아래 코드를 살펴봅시다.
var g = Grower()
g()
위 예제의 마지막 라인에서 g()
와 같이 Grower 인스턴스를 함수같이 호출하는 듯한 코드를 실행시켰습니다. 그런데 이게 에러가 안 납니다. 그리고 신기하게도 2를 리턴합니다.
계속 실행시키면 어떻게 될까요?
var g = Grower()
g()
// => 2
g()
// => 4
g()
// => 8
g()
// => 16
네 계속 불어납니다. Grower라는 이름에 어울리나요?
이렇게 callAsFunction
은 인스턴스를 직접 호출시키면 호출되는 특수한 메서드입니다. 활용 방법이야 무궁무진하겠지요?
'기술적인 이야기 > 애플 플랫폼 개발' 카테고리의 다른 글
iOS 시뮬레이터에서 애플 인증이 실패하는 문제 (899) | 2020.09.20 |
---|---|
애플 앱 심사 지침 업데이트 (1254) | 2020.09.01 |
Swift와 ObjC에서 Deprecated 처리하기 (0) | 2020.03.03 |
2020년 4월부터 소셜 로그인 지원 시 애플 인증 강제 (0) | 2020.02.18 |
Combine과 SwiftUI (1) | 2020.01.28 |
댓글