일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SWIFT
- @State
- graphql
- swift6
- nestjs
- init?
- RxSwift
- URL(string:)
- Operater
- Creating Operators
- dismiss
- ios14
- typeorm
- init
- NavigationLink
- RxCocoa
- @Binding
- Xcode
- NullObject
- RFC1738/1808
- Bug
- SwiftUI
- operator
- @Environment
- IOS
- subject
- vim
- @EnvironmentObject
- nonisolated
- Operators
- Today
- Total
Tunko Development Diary
associatedtype 이란? 본문
우선 associatedtype 타입은 제네릭에서 사용되는 타입입니다.
associatedtype은 연관타입이라고 불리며.
연관타입은 프로토콜의 일부분으로 타입에 플레이스홀더 이름을 부여합니다. 다시 말해 특정 타입을 지정해 사용할 수 있습니다.
연관타입의 실제 사용예시입니다.
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
// original IntStack implementation
var items = [Int]()
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
// conformance to the Container protocol
typealias Item = Int
mutating func append(_ item: Int) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Int {
return items[i]
}
}
위 코드를 하나씩 뜯어보면 Container 프로토콜을 채택한 구조체 입니다.
프로토콜에 선언한 associatedtype 인 Item에 Int 형을 할당하는것을 볼 수 있습니다.
typealias Item = Int
즉 protocol에 선언된 메서드인 mutating func append 에도 매개변수 타입이 Item 으로 되어있기에 Int로 바뀌게 됩니다.
그래서 구현부에는 mutating func append(_ item: Int) 이렇게 Int형 매개변수를 받게 됩니다.
두번째 예시
struct Stack<Element>: Container {
// original Stack<Element> implementation
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(_ item: Element) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element {
return items[i]
}
}
여기에선 Stack<Element> 를 직접적으로 선언 시 넣어주었습니다.
존재하는 타입에 연관 타입을 확장
extension Array: Container {}
이것이 가능한 이유는 Array 타입은 아래 Container에 선언된 append, count, subscript 가 모두 정의돼 있기 때문입니다.
protocol Container {
associatedtype Item: Equatable
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
프로토콜에 연관 타입의 제한 사용하기
연관 타입을 적용할 수 있는 타입에 조건을 걸어 제한을 둘 수 있습니다.
조건을 붙일때는 where 구문을 사용합니다.
이 조건에는 특정 타입인지 여부와 특정 프로토콜을 따르는지 여부등이 사용될 수 있습니다.
다음 예시
Suffix가 SuffixableContainer 프로토콜을 따르고 item 타입이 반드시 Container의 item타입 이여야 한다는 조건을 추가 한것 입니다.
protocol SuffixableContainer: Container {
associatedtype Suffix: SuffixableContainer where Suffix.Item == Item
func suffix(_ size: Int) -> Suffix
}
extension Stack: SuffixableContainer {
func suffix(_ size: Int) -> Stack {
var result = Stack()
for index in (count-size)..<count {
result.append(self[index])
}
return result
}
// Inferred that Suffix is Stack.
}
var stackOfInts = Stack<Int>()
stackOfInts.append(10)
stackOfInts.append(20)
stackOfInts.append(30)
let suffix = stackOfInts.suffix(2)
// suffix contains 20 and 30
Stack 의 연관 타입인 Suffix 또한 Stack입니다.
그래서 Stack의 suffix의 실행으로 또 다른 Stack을 반환하게 됩니다.
'Development > iOS 개발' 카테고리의 다른 글
swift) lazy variables (0) | 2022.06.29 |
---|---|
swift) ?? 연산자 (0) | 2022.06.20 |
swift) required init 요구 이니셜라이저 (0) | 2022.06.17 |
Swift ARC [weak self] 란? (0) | 2022.06.15 |
xcode 13 vim Editing Mode (0) | 2021.10.13 |