프로토콜은 struct, class, enum에게 원하는 프로퍼티를 요구할 수 있다.
struct, class, enum은 프로토콜이 요구하는 프로퍼티를 저장 / 연산 무엇으로든 구현할 수 있다.
let 키워드로 정의할 수 없는 연산 프로퍼티로도 구현할 수 있어야하기 때문에
프로토콜에서 프로퍼티는 항상 let이 아닌 var 키워드로 선언해야 한다.
protocol SomeProtocol { let mustBeSettable: Int { get set } ERROR! let doesNotNeedToBeSettable: Int { get } ERROR! }
let 키워드로 요구되는 프로퍼티는 컴파일에러가 생기고
때문에 타입 프로퍼티를 제외하고, 프로토콜에서 프로퍼티의 요구 형태는 다음 두가지 정도다.
protocol SomeProtocol { var doesNotNeedToBeSettable: Int { get } var mustBeSettable: Int { get set } }
이렇게 선언된 프로퍼티를 저장 / 연산 프로퍼티 무엇으로든 구현할 수 있다.
이 때 위 두개의 형태에서 지켜야 할 let / var 은 다음과 같다.
① gettable
protocol SomeProtocol { var doesNotNeedToBeSettable: Int { get } } // 저장 프로퍼티 struct varStoredProperty: SomeProtocol { var doesNotNeedToBeSettable: Int = 3 } struct letStoredProperty: SomeProtocol { let doesNotNeedToBeSettable: Int } // 연산 프로퍼티 struct getComputedProperty: SomeProtocol { var doesNotNeedToBeSettable: Int { get { 3 } set {} } } struct getSetComputedProperty: SomeProtocol { var doesNotNeedToBeSettable: Int { get { 3 } } }
(프로퍼티의 기본값은 신경쓸 필요없음)
gettable하게만 요구되는 프로퍼티는 우리가 할 수 있는 모든 형태의 저장 / 연산 프로퍼티로 구현해 줄 수 있다.
구현 형태에 제약이 생기는 경우는 gettable, settable 가능하게 요구하는 프로퍼티다.
② gettable, settable
protocol SomeProtocol { var doesNotNeedToBeSettable: Int { get set } } // 저장 프로퍼티 struct varStoredProperty: SomeProtocol { var doesNotNeedToBeSettable: Int = 3 } // ERROR!: Type 'letStoredProperty' does not conform to protocol 'SomeProtocol' struct letStoredProperty: SomeProtocol { let doesNotNeedToBeSettable: Int } // 연산 프로퍼티 struct getComputedProperty: SomeProtocol { var doesNotNeedToBeSettable: Int { get { 3 } set {} } } // ERROR!: Type 'getSetComputedProperty' does not conform to protocol 'SomeProtocol' struct getSetComputedProperty: SomeProtocol { var doesNotNeedToBeSettable: Int { get { 3 } } }
set, 즉 값을 마음대로 넣을 수 있어야한다는 속성을 무조건 가져야한다.
하지만 저장 프로퍼티의 let은 초기화를 제외하고 값을 설정할 수 없이 get만 가능하고
연산 프로퍼티도 set이 없으면 값을 설정할 수 없으므로 에러가 생긴다.
그래서 이걸 다 외워야하나 싶을수도 있는데
프로토콜에서 프로퍼티를 get없이 { set } 으로 요구함이 불가능하다는 점을 알고,
확장은 가능하나, 축소는 불가능하다는 점을 염두하면 굳이 외울필요는 없어보인다.
gettable로만 요구하는 프로퍼티를 준수할 때는 settable한 속성을 넣어서 확장시켜도 되지만
settable도 요구하는 프로퍼티를 gettable하게만 구현하면 축소되었으므로 불가능하다.