본문 바로가기
Swift

\Root.Value 는 (Root) -> Value이다

by zinozino 2023. 9. 26.

 

 

KeyPath 번역하자면 "특정 루트 유형에서 특정 결과 값 유형으로의 키 경로" 

 

다시 쉽게 이해하자면

특정 루트 유형(내가 알고 싶은 값을 담고있는 타입)에서 특정결괏값 유형(내가 알고 싶은 값)의 경로

class KeyPath<Root, Value>

class KeyPath<내가 알고 싶은 값을 가지고 있는 타입, 내가 알고 싶은 값의 타입>

예시

struct Video {
    let ratio: Ratio
    var quality: Float
}

struct Ratio {
    var horizontal: Int
    var vertical: Int
}

var gameVideo = Video(
    ratio: .init(
        horizontal: 16,
        vertical: 9),
    quality: 720
)

 

여기서  Ratio의 값을 접근해야한다면 

 

1. 프로퍼티에 접근한다 

 

2. 함수로 접근한다

 

3. KeyPath를 사용한다.

 

프로퍼티에 접근한다

2. 함수로 접근한다

func getVideoRatio(for video: Video) -> Ratio {
	return video.ratio
}

 

 

여기서  1과 2는 별차이가 없다. 1번은 내부에서 프로퍼티에서 Gette를 부르고 함수 또한 안에서 프로퍼티를 반환

 

 

3. KeyPath를 활용한다.

 

let 내가 알고싶은 값의 경로 
== 경로정보(\), 내가 알고 싶은 값을 가지고 있는 타입(Video), 내가 알고 싶은 값의 타입의 프로퍼티(Video.ratio)
== let ratioKeyPath = \Video.ratio

gameVideo[keyPath: gameKeyPath]

 

1,2 와 같이 값을 가져올 수 있습니다.

 

또한 KeyPath는 알고 싶은 프로퍼티에 대한 속성과 타입에 따라서 분류가 됩니다. 

struct Video {
    var ratio: Ratio // let -> var
    var quality: Float
}

let을 var바꾼다면 KeyPath에서 WritableKeyPath로 바뀌게 됩니다.

 

 

 

여기까지 간단하다면 간단하게 KeyPath에 대해서 알아보았습니다.

 

이번엔 드디어  함수측면에서 KeyPath를 알아보도록 할게요.

let ratioKeyPath = \Video.ratio

gameVideo[keyPath: gameKeyPath]

video.name은 내부에서 name프로퍼티의 getter함수가 실행되면  Video의 name(String)을 반환하죠?

 

2번째 함수도  타입을보자면

(Video) -> String 이죠!

 

여기서 Video타입에 KeyPath를 사용했지만 범용타입에 대한 KeyPath를 사용해 보도록 하겠습니다.

 

func get<Root, Value>(_ keyPath: KeyPath<Root, Value>) -> (Root) -> Value {
    return { root in root[keyPath: keyPath] }
}

 Generic 타입으로  KeyPath의 Root와 Value를 받도록 하였고,

반환타입을 (Root) -> Value 함수타입을 반환하도록 하였습니다. 

 

반환하는 코드를 보자면 KeyPath와 같은 Root타입을 받아서 해당 Root를 매개변수로 받은 KeyPath로 접근하여 Value를  가져오는 함수 타입을 반환합니다.

 

 

 

 

이제 Keypath도 get함수를 통해서 (Video) -> String를 반환하므로 KeyPath를 함수로 활용할 수 있게 되었습니다.

 

KeyPath는 존재하지 않는 경로에 대해선 컴파일러 단계에서 오류를 뱉어내기에 안전한 코딩이 가능합니다.

 

언젠간 이러한 KeyPath의 장점과 특징 그리고 오늘 만들어본 함수타입으로 변환하는  함수를 활용할 날이 있을 것 같습니다!

 

그럼 끄ㅌ!

 

 

참조

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/expressions/#Key-Path-Expression

https://www.pointfree.co/episodes/ep8-getters-and-key-paths

https://medium.com/2-minutes-read-tip/one-interesting-advantage-you-cant-miss-in-swift-keypaths-a7eb1e068a94#id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjZmNzI1NDEwMWY1NmU0MWNmMzVjOTkyNmRlODRhMmQ1NTJiNGM2ZjEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIyMTYyOTYwMzU4MzQtazFrNnFlMDYwczJ0cDJhMmphbTRsamRjbXMwMHN0dGcuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiIyMTYyOTYwMzU4MzQtazFrNnFlMDYwczJ0cDJhMmphbTRsamRjbXMwMHN0dGcuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDM5MTU4NTkzNzczOTIxNTQwNzIiLCJlbWFpbCI6Inl5eXFvckBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmJmIjoxNjk1NjU3MTM2LCJuYW1lIjoi7KCV7KeE7Zi4IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FDZzhvY0xPZVZqdmNrNV9rYXpIYkhoc1lIYWJkYm9mVFpZTUhNVHllcjI3MmFTQl9pbz1zOTYtYyIsImdpdmVuX25hbWUiOiLsp4TtmLgiLCJmYW1pbHlfbmFtZSI6IuyglSIsImxvY2FsZSI6ImtvIiwiaWF0IjoxNjk1NjU3NDM2LCJleHAiOjE2OTU2NjEwMzYsImp0aSI6IjI5ODczNWM4Zjk4N2Y2MmFkMTNhODNmODdmZWI5NmY5NTJkZTY2MWIifQ.VElgl1hZaV0LKk187c1Jqch-u_yBIcQPR12koj0BKeoNzcU6PWdHFeWVcbJbRpLvyp-rNiC_Tujg5TPF4aTVSWOOrr5yQ10FnjlGKpc2Z9bYF-grBNhfGkeaRu8sIECeI1IrzkHpcit7u6w3WFiW2Vfhuzc_Xp1PV93Xfxelfnk3o4MAUfja8mo-FLkq5Yq4Bt89TPg_bTrCXJmjDJ9Z50Y7vOGl1BH8USb2RK_3le4I34zmz4Ej20LLZDJ3h9BjOR75OrdDYWPMn82CUy4DqtGnzn4Av0yWHd0fp77qfUL3k1XaQALLEYvsajXnKzHctmKuzJClrQXKdnCE9ZxUQw