cleanUrl: /programming/opaque-return-type
저번 포스트에서 Generic Protocol의 용도와 한계에 대해서 다뤘습니다. 간단히 복습해 보자면 다음과 같이 정리 할 수 있겠습니다.
코드로 보면 아래와 같습니다.
protocol Identifiable {
associatedtype ID_TYPE: Equtable
var id: ID_TYPE { get set }
init()
}
class Student: Identifiable {
var id: Int
required init() {
id = 0
}
}
class AppleDevice: Identifiable {
var id:String
required init() {
id = "asdf-1234"
}
}
func getSomeIdentifiable() -> Identifiable {
return AppleDevice() // Compile Error!!
}
이 때 컴파일 에러의 내용은 다음과 같았습니다.
<aside> ⚠️ Protocol 'Identifiable' can only be used as a generic constraint because it has Self or associated type requirements
</aside>
Generic Protocol은 “Generic Constraint”로만 사용될 수 있다고 합니다. 이게 무슨 말일까요? 말로 설명하는 것 보다, 아래 코드로 보여 드리는 편이 이해가 쉬울 것 같습니다.
func getSomeIdentifiable<T:Identifiable>() -> T {
return T() // Identifiable이 T에 대한 제약(Constraint)로 사용되고 있습니다.
}
var iPhone:AppleDevice = getSomeIdentifiable()
print(iPhone.id) // id타입은 String
var bob:Student = getSomeIdentifiable()
print(bob.id) // id타입은 Int
이렇게
getSomeIdentifiable
이 사용되는 곳에서컴파일러는 어렵지 않게 iPhone의 id 타입을 추론할 수 있고, 불평 없이 컴파일을 할 수 있게 됩니다.
자, 그러면 아래와 같은 상황은 어떨까요?
var someIdentifiable = getSomeIdentifiable()
// id타입을 추론 할 수가 없습니다 ㅠㅠㅠ
어떤 Identifiable
을 원하는지를 사용하는 측에서 명시해 주질 않으니까, 당연히 컴파일러는 불만을 표시 할 수밖에 없습니다. 그러면 이렇게 생각 할 수도 있습니다. “그러면 언제나 사용하는 측에서 Identifiable의 타입을 명시해 주면 되는 거 아냐?