불명확 타입

박형석·2021년 12월 13일
0

Swift

목록 보기
17/20
post-thumbnail

불명확 타입(Opaque Type)이란?

  • 반환 타입에 불명확 타입(Opaque Type)을 사용하면 반환할 타입의 정확한 타입을 알려주지 않은채로 반환하겠다는 의미다.
  • 반환 타입 위치에 프로토콜을 쓰면서 앞에 some
    → "이 프로토콜을 준수하는 어떤 타입 중에 하나일 것은 분명하다"는 의미
// 반환되는 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()

이렇게 외부에서 정확한 타입은 알 수 없지만, 해당 프로토콜을 준수하는 '어떤 타입'을 반환한다는 약속을 불명확 타입으로 표현할 수 있다. 함수, 메서드 뿐만 아니라 프로퍼티나 서브스크립트 타입에서도 사용 가능하다.

profile
IOS Developer

0개의 댓글