Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- MVVM
- Refactoring
- clean architecture
- uitableview
- Protocol
- 리펙터링
- swiftUI
- combine
- 클린 코드
- uiscrollview
- ios
- 리펙토링
- UITextView
- tableView
- Xcode
- UICollectionView
- SWIFT
- Observable
- Clean Code
- 스위프트
- ribs
- 리팩토링
- rxswift
- map
- RxCocoa
- swift documentation
- collectionview
- 애니메이션
- HIG
- Human interface guide
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] Type Erasure 이해하기 (any, some, unboxing 개념, 유연한 프로그래밍) 본문
iOS 응용 (swift)
[iOS - swift] Type Erasure 이해하기 (any, some, unboxing 개념, 유연한 프로그래밍)
jake-kim 2023. 2. 24. 22:01Type Erasure 알기 전 알아야할것
- Type Erasure를 먼저 살펴보기 전에, 왜 Type Erasure와 같은 기능이 나왔는지 이해하기 위해 아래처럼 확장성 있는 기법들을 알아보기
사전 지식1) 클라이언트 코드 쪽에서 유연한 프로그래밍 (= 추상화)
* 클라이언트 코드: 모듈, 함수, 메소드 등 이 것을 사용하는 코드 부분을 의미
- 대표적인 방법 - Generics
func compare<T: Comparable>(param1: T, param2: T) -> Bool {
param1 < param2
}
- generics는 리턴 타입에는 적용이 어려운 단점
func someRet<T: Comparable>() -> T {
10 // Cannot convert return expression of type 'Int' to return type 'T'
}
- enum 타입을 이용하여 리턴 타입을 여러개 두는 방법
enum SomeRetType {
case int(Int)
case string(String)
}
func someRet() -> SomeRetType {
if true {
return .int(0)
} else {
return .string("string")
}
}
- protocol을 사용하는 방법 (프로토콜 지향 방법)
protocol MyAnyView {}
struct MyView1: MyAnyView {}
struct MyView2: MyAnyView {}
func someView() -> MyAnyView {
if true {
return MyView1()
} else {
return MyView2()
}
}
사전 지식2) any와 some 키워드 이해하기 (opaque type)
- some과 any는 반대의 개념
- some은 타입을 제한
- any는 타입을 추상화 (= Type Erasure)
/// Collection 타입으로 제한
some Collection
/// Collection 타입으로 추상화
any Collection
- some, any 타입 사용
// Error: Protocol 'Collection' can only be used as a generic constraint because it has Self or associated type requirements
func someList1() -> Collection {
return [1, 2, 3]
}
func someList2() -> some Collection {
return [1, 2, 3]
}
func someList3() -> any Collection {
return [1, 2, 3]
}
- any와 some의 차이점은?
- some은 배열의 Element 타입이 모두 동일해야하지만, any는 달라도 무방
protocol SomeType {}
struct Struct1: SomeType {}
struct Struct2: SomeType {}
func someList4() -> [some SomeType] {
return [Struct1(), Struct2()] // Error: Type of expression is ambiguous without more context
}
func someList5() -> [any SomeType] {
return [Struct1(), Struct2()]
}
- 애플에서 제안하는 some, any 타입 사용
- some을 우선적으로 사용하고 any가 필요한 경우만 그때 any를 사용할 것
- 이유 > 프로그래밍에서는 개발자가 예측 가능한 프로그래밍을 해야, 유지보수가 용이한데 추상화를 크게 할 수록 예측 가능성이 떨어지므로
Type Erasure 란?
- Type Erasure란 구체적인 특정 타입을 추상적인 타입으로 바꾸는 것
- 타입을 지운다는 의미 = 추상화 한다는 의미
- 타입을 지우는 이유는 사용하는 쪽에서 유연한 프로그래밍을 위함
- (위에서 알아본 any가 바로 type erasure의 한 종류)
- 애플에서는 비유적으로 type erased를 표현
- any는 타입을 없애기 위해 상자를 씌운다는 의미 (= 추상화)
- 상자를 씌운다는 의미는 또한 상자를 언제든 unboxing 하여 사용할 수 있다는 의미
ex) SwiftUI에서 AnyView 타입으로 변경하기 위한 eraseToAnyView를 따로 extension으로 추가하고, Image와 같은 곳에서 View로 변환하여 사용할 수 있도록 구현
- Image에서 eraseToAnyView를 사용하여 Image의 타입을 지우고 AnyView를 반환하여 사용하는 쪽에서 View로 사용할 수 있도록 제공
extension View {
var eraseToAnyView: AnyView { AnyView(self) }
}
public extension Image {
static var splashImage: (_ imageName: String) -> AnyView = { imageName in
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.eraseToAnyView
}
}
정리
- type erase는 타입을 추상화 시키는 것이고, 핵심은 다시 타입을 되돌려서 사용이 가능 (unboxing)
- any 키워드는 type erase의 대표적인 방법이고, some 키워드는 타입을 제한하는 방법 중 하나임을 이해
- 예측 가능한 프로그래밍을 위해서 되도록 any보다는 some 키워드를 사용할 것
* 참고
https://developer.apple.com/videos/play/wwdc2022/110352/
https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html
'iOS 응용 (swift)' 카테고리의 다른 글
Comments