안녕하세요~! 오늘은 Swift5.1에서 소개된 불투명 타입 Opaque type에 대해서 소개해 드리려고 합니다~!
명확한 반환 타입을 외부에 제공하는 대신, Opaque 반환(return) 타입을 가진 함수,
메서드는 자신의 반환타입 정보를 외부에 숨길 수 있습니다.
Return 타입을 숨기는 것은 모듈로 호출되는 코드와 모듈 사이에서 유용하게 사용할 수 있습니다.
제네릭(구현부 추상화), 호출하는 곳에서는 구체적인 타입(예 : <Int>)을 아는 상태에서 사용했다면,
Opaque type은 반대로 구현부는 구체적인 타입을 알고 있지만, 호출하는 곳에서는 특정 프로토콜만 알 수 있습니다.
- Generic -
구현부 - 추상화하여 작성
호출부 - 구체적인 타입 지정 (타입을 알 수 있음)
- Opaque Type-
구현부 - 구체적인 타입 지정 (타입을 알 수 있음)
호출부 - 추상화하여 작성
아래 총 4개의 상황에서 사용할 수 있습니다.
- 함수(메소드)의 리턴타입
- stored property 타입
- computed property 타입
- 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을 사용하여 리턴 타입의 정보를 숨길 수 있다"고 말하는 것입니다.
오늘은 여기까지입니다~! 감사합니다.
'Apple > Apple_Swift' 카테고리의 다른 글
swift5.5 스레드 동시성 문제 및 해결 방안 (async/await, Actor) (0) | 2023.03.21 |
---|---|
Swift 5.1 Static and class subscripts (SE-0254) (0) | 2023.03.17 |
Swift5.1 구조체 멤버별 이니셜라이저(Memberwise Initializer)의 기본값 합성 SE-0242 (0) | 2023.01.16 |
Swift5.0 SE-0225 배수 구하기 isMultiple(of:) (0) | 2023.01.11 |
Swift5.0 중첩된 Optionals(??) 평면화 하기 SE-0230 (0) | 2023.01.10 |