Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] KeyPath, map(\.) 연산자 본문

iOS 응용 (swift)

[iOS - swift] KeyPath, map(\.) 연산자

jake-kim 2021. 12. 11. 22:36

KeyPath란?

  • 특정 루트 유형(class 타입, struct 타입)에서 value type으로의 참조를 의미
  • Property의 reference값을 의미 (c에서의 포인트 개념과 유사)

* 구체적인 KeyPath, KVC, KVO 개념은 다음 포스팅 글 참고

KeyPath 사용 방법

  • KeyPath 참조 얻어내는 방법
let userNameKeyPath = \\User.name
print(userNameKeyPath) // Swift.KeyPath<ExSyntax.ViewController.User, Swift.String>
  • KeyPath 참조를 통해 값에 접근하는 방법
let userNameKeyPath = \\User.name
print(userNameKeyPath) // Swift.KeyPath<ExSyntax.ViewController.User, Swift.String>

let user1 = User(name: "jake", email: "a@a.com", phoneNumber: "010-1111-5678")
let user = user1[keyPath: userNameKeyPath]
print(user) // jake
  • 객체 정의 자체 내에서 KeyPath를 사용할 때는 자기 자신의 클래스 이름 생략이 가능
class User {
	func getName() -> String {
		return self[keyPath: \\.name]
	}
}

Swift 5.2+, KeyPath를 통한 편리한 property 접근

  • KeyPath를 통해 Higher Order Function을 더욱 편리하게 사용 가능
    • map
    // sample data
    let user1 = User(name: "jake", email: "a@a.com", phoneNumber: "010-1111-5678")
    let user2 = User(name: "kim", email: "b@b.com", phoneNumber: "010-2222-5678")
    let user3 = User(name: "jane", email: "c@c.com", phoneNumber: "010-3333-5678")
    let users = [user1, user2, user3]
    
    // KeyPath를 사용하지 않은 경우
    let names = users.map { $0.name }
    
    // KeyPath를 사용한 경우
    let namesUsingKeyPath = users.map(\.name) // users.map { $0[keyPath: \\User.email] } 와 동일
    • filter
    // filter에서 KeyPath를 통한 equal 연산자 정의
    func ==<T, V: Equatable>(lhs: KeyPath<T, V>, rhs: V) -> (T) -> Bool {
        return { $0[keyPath: lhs] == rhs }
    }
    
    // KeyPath를 사용하지 않은 경우
    let engineers = users.filter { $0.job == .engineer }
    
    // KeyPath를 사용한 경우
    let namesIncludeJUsingKeyPath = users.filter(\\.job == .engineer)
    

* 참고

- https://learnappmaking.com/swift-keypath-how-to/

Comments