제네릭은 특히 프로토콜에서 빛을낸다. 프로토콜에 제네릭이 적용되면 다형성을 구현하는데 큰 도움이 된다.
특정 프로토콜이 서로 다른 타입에 더욱 자유롭게 채택할 수 있도록 하여 통일성을 높이고, 재활용성도 함께 높아진다.
하지만 프로토콜 자체가 제네릭 파라미터를 가질 순 없다. 프로토콜은 메서드나 속성을 구체화할 의무가 없고 최소 요구사항만을 갖기 때문이다.
프로토콜에서 타입이 제네릭하게 메서드나 속성을 구현할 수 있도록 연관타입(associatedtype)을 활용한다.
연관타입을 요구사항으로 갖는 프로토콜을 채택하면 해당 연관타입을 각 타입에서 구체화할 수 있고 그 전까지는 명시되지 않는다.
연관타입과 제네릭을 함께 사용
protocol Container{
associatedtype Item // 연관 타입 선언(associatedtype)
var count: Int { get }
mutating func append(_ from: Item)
subscript(i: Int) -> Item { get }
}
struct Stack<Element>: Container{ // Element는 item에 대응
typealias Item = Element
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
// Container 프로토콜 구현
var count: Int {
return items.count
}
mutating func append(_ item: Element) {
self.push(item)
}
subscript(i: Int) -> Element {
return items[i]
}
}
}
Container 프로토콜은 Item이라는 연관타입을 선언한다.
Stack구조체는 Container프로토콜을 따르며 Element라는 제네릭 타입을 typealias를 통해 Item으로 대체하고있다.
결론
Swift의 프로토콜에서 연관타입과 제네릭은 유용한 기능으로 *객체간의 인터페이스를 추상화하고 재사용 가능한 코드를 작성하는데 도움으 준다.
연관타입과 제네릭을 함께 사용하면 제네릭 타입에서 연관타입을 사용할 수 있다. 이를 통해 코드의 재사용성과 유지보수성을 향상시킬 수 있다.
* 객체간의 인터페이스를 추상화한다.
https://clamp-coding.tistory.com/430