iOS 응용 (SwiftUI)
[iOS - SwiftUI] generic과 opaque type 차이, some view와 protocol 반환의 차이 (#opaque types, #existential types)
jake-kim
2024. 8. 5. 01:04
generic과 opaque type 개념
- generic은 타입의 유연성을 제공하여 사용하는쪽에서 타입을 정하게끔하는 방법
ex) generic을 사용하는 가장 대표적인 예제 - Stack 구현
struct Stack<Element> {
private var elements: [Element] = []
mutating func push(_ element: Element) {
elements.append(element)
}
mutating func pop() -> Element? {
elements.popLast()
}
func peek() -> Element? {
elements.last
}
func isEmpty() -> Bool {
elements.isEmpty
}
}
- opaque type은 구현부에서는 타입이 구체적인 타입을 사용하지만, 반환 타입은 감추는 것
ex) SwiftUI에서는 opaque type인 some 키워드를 사용하여 View를 반환하는 body 프로퍼티가 존재
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
.font(.largeTitle)
.padding()
}
}
}
generic과 opaque 타입의 차이
- generic은 사용하는 쪽에서 타입을 결정하고, 컴파일러 최적화가 opaque 타입보다 떨어짐
- opaque 타입은 정의하는 쪽에서 타입이 구체적인 타입을 사용하게되며 컴파일러가 미리 알 수 있으므로 최적화가 가능
opaque 타입과 protocol을 반환하는 것의 차이
- 단순 protocol을 반환하는것은 dynamic dispatch를 사용하며, opaque 타입을 반환하면 static dispatch가 되므로 최적화에 더욱 유리
ex) opaque 타입에 분기문을 넣어서 동적으로 concrete 타입이 정해지게 만들면 컴파일 에러가 발생
protocol SomeProtocol {}
struct A: SomeProtocol {}
struct B: SomeProtocol {}
func someFunc1() -> SomeProtocol {
if Bool.random() {
A()
} else {
B()
}
}
func someFunc2() -> some SomeProtocol {
if Bool.random() {
A() // error: Branches have mismatching types 'A' and 'B'
} else {
B()
}
}
* 참고: https://medium.com/kerege/swift-concepts-opaque-types-existential-types-93326a3e55df