// 반환되는 WrappedPrize가 정확히 먼지는 모르겠지만, 이 프로토콜을 준수하는 녀석인건 분명해!
func dispenseRandomPrize() -> some WrappedPrize {
// 내부에선 이 프로토콜을 준수하는 어떤 녀석을 반환. 하지만 외부는 구체적으로 이 친구가 누군지 모름
return WrappedGundam()
}
제네릭 : 어떤 타입이 들어올지 모르는 상태로 플레이스 홀더를 만들어 준다. 외부에서 타입을 지정해주는 것
불명확 타입 : 외부에서는 어떤 타입이 반환될지 모른다는 것. 내부에서 타입을 정해서 내보내게 되는데, 밖에서는 정확히 어떤 타입인지는 몰라도 쓸 수 있는 것. 역제네릭 타입이라고도 불림
비슷한 점? 제네릭의 플레이스 홀더 타입과 불명확 타입의 반환 타입을 프로토콜로 지정해 줄 수 있다는 정도
그냥 프로토콜을 반환 타입으로 정의하면 안되나?
프로토콜 정의부에 associatedType을 사용했거나, Self 타입을 사용하는 프로토콜은 타입 자체가 제네릭하게 됨. 그래서 반환 타입으로 사용X
protocol WrappedPrize {
associatedtype Prize
var wrapColor: String! { get }
var prize Prize! { get }
}
protocol Gundam { }
protocol Pocketmon { }
struct WrappedGundam: WrappedPrize {
var wrapColor: String!
var prize: Gundam!
}
struct WrappedPocketmon: WrappedPrize {
var wrapColor: String!
var prize: Pocketmon!
}
struct PrizeMachine{
// WrappedPrize는 '제네릭 타입 제약'이 있어야 사용할 수 있는 타입, 반환X
// 왜냐하면 WrappedPrize 안에 있는 Prize를 추론할 힌트가 없기 때문
func dispenseRandomPrize() -> WrappedPrize {
return WrappedGundam()
}
}
// 다음처럼 불명확 타입으로 개선
struct PrizeMachine{
func dispenseRandomPrize() -> some WrappedPrize {
return WrappedGundam()
}
}
let machine = PrizeMachine()
// 포장된 건담이 나온다.
let wrappedPrize = machine.dispenseRandomPrize()
이렇게 외부에서 정확한 타입은 알 수 없지만, 해당 프로토콜을 준수하는 '어떤 타입'을 반환한다는 약속을 불명확 타입으로 표현할 수 있다. 함수, 메서드 뿐만 아니라 프로퍼티나 서브스크립트 타입에서도 사용 가능하다.