🔥 제네릭 접근 수준

261자
3분

Swift에서 제네릭 타입이나 제네릭 함수의 접근 수준은 해당 제네릭 타입 또는 함수 자체의 접근 수준과 해당 제네릭의 타입 매개변수에 적용되는 타입 제약의 접근 수준 중 최소 접근 수준으로 결정됩니다.

이게 무슨 말일까요? 예제 코드를 통해 하나씩 살펴보도록 하죠.

public struct Stack<T> {
    // 내부 속성과 메서드의 접근 수준은 public입니다.
    public var items = [T]()
    public mutating func push(_ item: T) {
        items.append(item)
    }
    public mutating func pop() -> T {
        return items.removeLast()
    }
}
swift

위 코드에서 Stack 구조체는 public 접근 수준으로 선언되어 있습니다. 그리고 Stack 내부의 속성과 메서드들도 모두 public으로 선언되어 있네요. 이 경우, Stack 구조체의 타입 매개변수 T에는 어떤 타입 제약도 적용되어 있지 않기 때문에, Stack 구조체의 접근 수준은 public이 됩니다.

그런데 만약 다음과 같이 타입 매개변수 Tprivate 접근 수준의 타입을 타입 제약으로 적용하면 어떻게 될까요?

private protocol PrivateElement {
    var value: Int { get set }
}
 
public struct Stack<T: PrivateElement> {
    public var items = [T]()
    public mutating func push(_ item: T) {
        items.append(item)
    }
    public mutating func pop() -> T {
        return items.removeLast()
    }
}
swift

이 경우, Stack 구조체 자체는 public으로 선언되었지만, 타입 매개변수 T에 적용된 타입 제약인 PrivateElement 프로토콜이 private 접근 수준을 가지고 있습니다. 따라서 Stack 구조체의 실제 접근 수준은 private이 되는 거예요.

이렇게 제네릭 타입이나 함수의 접근 수준은 해당 제네릭의 타입 매개변수에 적용되는 타입 제약의 접근 수준에 의해서도 영향을 받는답니다.

실제로 위 코드에서 Stack 구조체를 다른 모듈에서 사용하려고 하면, PrivateElementprivate 접근 수준을 가지고 있기 때문에 컴파일 에러가 발생합니다.

이처럼 제네릭을 설계할 때는 타입 매개변수에 적용하는 타입 제약의 접근 수준도 함께 고려해야 한다는 점, 꼭 기억해 두시기 바랍니다!