Swift5.1 불투명 타입 (Opaque type) some Type SE-0244

안녕하세요~! 오늘은 Swift5.1에서 소개된 불투명 타입 Opaque type에 대해서 소개해 드리려고 합니다~!

 

명확한 반환 타입을 외부에 제공하는 대신, Opaque 반환(return) 타입을 가진 함수,

메서드는 자신의 반환타입 정보를 외부에 숨길 수 있습니다.

Return 타입을 숨기는 것은 모듈로 호출되는 코드와 모듈 사이에서 유용하게 사용할 수 있습니다.

 

제네릭(구현부 추상화), 호출하는 곳에서는 구체적인 타입(예 : <Int>)을 아는 상태에서 사용했다면,

Opaque type은 반대로 구현부는 구체적인 타입을 알고 있지만, 호출하는 곳에서는 특정 프로토콜만 알 수 있습니다.

 

- Generic -
구현부 - 추상화하여 작성
호출부 - 구체적인 타입 지정 (타입을 알 수 있음) 

- Opaque Type- 
구현부 - 구체적인 타입 지정 (타입을 알 수 있음)
호출부 - 추상화하여 작성

 

아래 총 4개의 상황에서 사용할 수 있습니다.

  1. 함수(메소드)의 리턴타입
  2. stored property 타입
  3. computed property 타입
  4. subscripts

 

아래 예제를 보면서 더 구체적으로 이해 해보겠습니다.

enum CardType {
    case gold
    case platinum
}

protocol CardNumberProtocol {
}

extension String: CardNumberProtocol {
}

protocol Card {
    associatedtype CardNumber: CardNumberProtocol
    var type: CardType { get set }
    var limit: Int { get set }
    var number: CardNumber { get set }
    
    func validate(cardNumber number: CardNumber)
}

'Card'라는 프로토콜을 하나 정의했습니다.

여기서 주목할 점은 카드 넘버는 'CardNumberProtocol'을 따르는 associatedtype을 정의 했습니다.

사용자는 해당 프로토콜을 구현할때, 명시한 타입을 알 수 있습니다.

struct MasterCard: Card {
    typealias CardNumber = String
    var type: CardType = .platinum
    var limit = 500_000
    var number = "5010 2034 4070 1292"
    
    func validate(cardNumber number: String) {
    }
}

struct VisaCard: Card {
    typealias CardNumber = String
    var type: CardType = .gold
    var limit = 1_000_000
    var number = "1234 5699 2357 3933"
    
    func validate(cardNumber number: String) {
    }
}

그리고 'Card'프로토콜을 따르는 2개의 카드 (마스터, 비자) 카드를 정의 했습니다.

타입은 두 곳 모두 String으로 정의했네요.

// 대출 자격 여부
func getLoanEligibility() -> Bool {
    getUserCard().limit >= getLoanEligibilityCard().limit
}

// 유저 카드
func getUserCard() -> some Card {
    MasterCard()
}

// 대출 자격이 되는 카드
func getLoanEligibilityCard() -> some Card {
    VisaCard()
}

구현부에서는 associatedtype에 대해 구체적인 타입을 알고 있습니다.

하지만 리턴을 받는 호출부에서는 어떤 타입이 오는지 알 수 없으므로 

some 키워드를 리턴 타입 옆에 붙여서 처리해야 합니다.

 

Opaque Type 역 제네릭 타입(reverse generic type)으로 불리는 이유이기도 한데요
이러한 특성때문에 "Opaque Type을 사용하여 리턴 타입의 정보를 숨길 수 있다"고 말하는 것입니다. 

 

오늘은 여기까지입니다~! 감사합니다.