Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
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
Archives
Today
Total
관리 메뉴

J

[Swift] associatedtype 본문

Swift

[Swift] associatedtype

yujaehui 2024. 4. 18. 00:35

1. `associatedtype`이란?

`associatedtype`은 프로토콜 내에서 사용되는 타입의 플레이스홀더를 정의하는 데 사용.

이를 통해 프로토콜을 채택하는 타입이 구체적인 타입을 지정하도록 요구할 수 있음.

 

`associatedtype`은 프로토콜을 보다 유연하고 재사용 가능하게 만들어 줌.

특히, `Generic`과 함께 사용하면 강력한 타입 추론과 코드 유연성을 제공할 수 있음.


2. `associatedtype` 기본 문법

protocol ProtocolName {
    associatedtype TypeName
    // 프로토콜 요구 사항
}
  • `associatedtype`은 프로토콜의 타입 매개변수와 같은 역할.
  • 프로토콜을 채택한 타입은 `associatedtype`으로 선언된 타입을 구현하면서 구체적인 타입으로 정의해야 함.

3. `associatedtype` 사용 예제

protocol Container {
    associatedtype Item
    var items: [Item] { get set }
    mutating func addItem(_ item: Item)
}

struct IntContainer: Container {
    var items: [Int] = []

    mutating func addItem(_ item: Int) {
        items.append(item)
    }
}

struct StringContainer: Container {
    var items: [String] = []

    mutating func addItem(_ item: String) {
        items.append(item)
    }
}
  • `Container` 프로토콜은 `associatedtype Item`을 사용하여 타입 플레이스홀더를 정의.
  • `IntContainer`는 `Item`을 `Int`로, `StringContainer`는 `Item`을 `String`으로 정의.

4. `associatedtype`과 `Generic`

`associatedtype`은 `Generic`과 자연스럽게 결합되어 사용할 수 있음.

func printItems<T: Container>(from container: T) {
    for item in container.items {
        print(item)
    }
}

var intContainer = IntContainer()
intContainer.addItem(1)
intContainer.addItem(2)

printItems(from: intContainer) // 1, 2
  • 여기서 `printItems` 함수는 `Container` 프로토콜을 준수하는 어떤 타입이든 받아서 동작.

5. `associatedtype`과 `Generic`의 차이점

특징 `associatedtype` `Generic`
사용 위치 프로토콜에서 사용 함수, 클래스, 구조체, 열거형에서 사용
타입 지정 시점 프로토콜을 채택하는 타입이 지정 함수 호출 시 또는 객체 생성 시 지정
주 용도 프로토콜의 타입 추론 및 유연성 제공 다양한 타입에서 동작하는 코드 작성

6. `associatedtype`의 타입 제약

`associatedtype`도 `Generic`처럼 타입 제약(Type Constraints)을 추가할 수 있음.

protocol Container {
    associatedtype Item: Equatable
    var items: [Item] { get set }
    mutating func addItem(_ item: Item)
}

struct IntContainer: Container {
    var items: [Int] = []

    mutating func addItem(_ item: Int) {
        items.append(item)
    }
}
  • `associatedtype Item`: `Equatable`은 `Item`이 반드시 `Equatable` 프로토콜을 준수하도록 강제.

7. `associatedtype`의 실질적 사용 예

`IteratorProtocol`

Swift의 표준 라이브러리에서 `associatedtype`을 사용하는 대표적인 예는 `IteratorProtocol`.

protocol IteratorProtocol {
    associatedtype Element
    mutating func next() -> Element?
}
  • 이를 준수하는 타입은 `Element`를 구체적인 타입으로 정의해야 함.
struct IntIterator: IteratorProtocol {
    var current = 0

    mutating func next() -> Int? {
        if current < 3 {
            defer { current += 1 }
            return current
        } else {
            return nil
        }
    }
}

var iterator = IntIterator()
while let value = iterator.next() {
    print(value) // 0, 1, 2
}

`Sequence`

Swift의 `Sequence`도 `associatedtype`을 사용.

protocol Sequence {
    associatedtype Iterator: IteratorProtocol
    func makeIterator() -> Iterator
}

  • `makeIterator` 메서드는 `IteratorProtocol`을 준수하는 타입을 반환해야 함.
struct Countdown: Sequence {
    var start: Int

    func makeIterator() -> CountdownIterator {
        return CountdownIterator(current: start)
    }
}

struct CountdownIterator: IteratorProtocol {
    var current: Int

    mutating func next() -> Int? {
        if current > 0 {
            defer { current -= 1 }
            return current
        } else {
            return nil
        }
    }
}

let countdown = Countdown(start: 3)
for number in countdown {
    print(number) // 3, 2, 1
}

8. 언제 `associatedtype`을 사용할까?

  • 프로토콜이 타입에 의존적인 동작을 정의할 때.
  • `Generic`처럼 다양한 타입에서 동작하지만, 구체적인 타입 정의는 프로토콜을 채택하는 타입에 맡기고 싶을 때.
  • 프로토콜 요구 사항이 연관 타입 간의 관계를 포함할 때.

9. 결론

Swift의 `associatedtype`은 프로토콜의 유연성을 극대화하는 강력한 도구.

이를 활용하면 특정 타입에 의존하지 않는 일반화된 프로토콜을 정의할 수 있음.

특히, `Generic`과 결합하면 코드의 재사용성을 더욱 높일 수 있음.

그러나 지나치게 복잡한 타입 의존성을 도입하지 않도록 적절히 사용하는 것이 중요.

'Swift' 카테고리의 다른 글

[Swift] weak, unowned  (0) 2024.04.18
[Swift] self / Self  (0) 2024.04.18
[Swift] Protocol  (0) 2024.04.18
[Swift] Generic  (0) 2024.04.15
[Swift] GCD vs Swift Concurrency: 스레드 관리와 성능  (0) 2024.04.15