TIL: 프로토콜 확장의 적용 제한

Royce·2025년 3월 29일

Swift 문법

목록 보기
54/63

프로토콜 확장의 적용 제한

  • Swift의 프로토콜 확장은 모든 타입에 기본 구현을 제공할 수 있지만, 특정 조건을 만족하는 타입에만 적용되도록 제한할 수도 있다
  • 이 방식은 프로토콜을 확장하면서 특정 프로토콜을 추가로 채택한 타입에만 기본 구현을 제공할 때 유용하게 사용된다

프로토콜 확장 제한의 개념

  • Swift에서는 where 절을 사용하여, 특정 조건을 만족하는 타입에만 프로토콜 확장이 적용되도록 제한할 수 있다
  • 예를 들어, 특정 프로토콜을 채택한 타입에만 확장이 적용되도록 설정할 수 있다

Self 키워드의 의미

  • Swift에서 Self 는 다음 두 가지 의미로 사용된다
  1. 타입 자신을 의미한다 (클래스, 구조체, 열거형 등)
  2. 프로토콜에서 Self 는 프로토콜을 채택하는 타입을 의미한다
    • 즉, where Self: 특정 프로토콜 이라는 의미는 해당 타입이 특정 프로토콜을 채택했을 경우에만 적용되도록 제한하는 것을 뜻한다

예제 코드 (Self를 사용한 프로토콜 확장의 적용 제한)

// 기본 프로토콜 정의
protocol Remote {
    func turnOn()        // 리모콘 켜기 기능을 요구하는 메서드
    func turnOff()       // 리모콘 끄기 기능을 요구하는 메서드
}

// 모든 Remote 타입에 기본 구현 제공 (프로토콜 확장)
extension Remote {
    func turnOn() { print("리모콘 켜기") }
    func turnOff() { print("리모콘 끄기") }
}

// Bluetooth 기능을 정의하는 새로운 프로토콜
protocol Bluetooth {
    func blueOn()         // 블루투스 켜기 기능을 요구하는 메서드
    func blueOff()        // 블루투스 끄기 기능을 요구하는 메서드
}

/** 
 Bluetooth 프로토콜의 기본 구현 제공 (조건부 확장)
 - 여기서 Self는 이 확장이 적용될 타입 자체를 의미한다
 - where Self: Remote 의 의미는 Bluetooth 프로토콜을 채택하는 타입이 Remote 프로토콜도 채택해야만 적용된다는 뜻이다
 - 즉, Bluetooth와 Remote를 동시에 채택한 타입에만 이 확장이 적용된다
*/
extension Bluetooth where Self: Remote {  
    func blueOn() { print("블루투스 켜기") }
    func blueOff() { print("블루투스 끄기") }
}

// 새로운 타입 정의 (클래스를 사용하여 구현)
class SmartPhone: Remote, Bluetooth { 
    // 별도의 구현 없이도 기본 구현을 사용할 수 있음 (조건을 만족하기 때문)
}
  1. Remote 프로토콜 정의
    • turnOn()turnOff() 메서드를 요구하는 프로토콜이다
    • 모든 Remote 타입에 대해 기본 구현을 제공한다
  2. Bluetooth 프로토콜 정의
    • blueOn()blueOff() 메서드를 요구하는 프로토콜이다
    • 초기에는 기본 구현이 제공되지 않는다
  3. 프로토콜 확장에 where Self: Remote 조건 추가
    • Self 는 이 확장이 적용될 타입 자신을 의미한다
    • where Self: Remote 라는 의미는 Bluetooth 프로토콜을 채택하는 타입이 Remote 프로토콜도 동시에 채택해야만 확장이 적용된다는 의미이다
    • 즉, Remote 를 채택하지 않는 타입에서는 이 확장이 적용되지 않는다
  4. SmartPhone 클래스의 동작 방식
    • SmartPhone 클래스는 RemoteBluetooth 를 모두 채택하고 있기 때문에 확장에서 제공하는 기본 구현을 모두 사용할 수 있다

사용 예제 (코드 실행 예제)

let phone = SmartPhone()
phone.turnOn()      // 출력: 리모콘 켜기 (Remote 프로토콜의 확장에서 제공된 기본 구현 사용)
phone.turnOff()     // 출력: 리모콘 끄기 (Remote 프로토콜의 확장에서 제공된 기본 구현 사용)
phone.blueOn()      // 출력: 블루투스 켜기 (Bluetooth 프로토콜의 조건부 확장에서 제공된 기본 구현 사용)
phone.blueOff()     // 출력: 블루투스 끄기 (Bluetooth 프로토콜의 조건부 확장에서 제공된 기본 구현 사용)

적용 제한의 의미와 장점

  1. 타입의 제약을 설정할 수 있다
    • where 절을 사용하여 프로토콜 확장을 적용할 타입을 제한할 수 있다
    • 예를 들어, Bluetooth 프로토콜은 Remote 프로토콜을 채택한 타입에서만 사용할 수 있도록 설정되었다
  2. 확장의 적용 범위를 세밀하게 제어할 수 있다
    • 모든 타입에 대해 확장을 적용하는 대신, 특정 조건을 만족하는 타입에만 확장을 적용할 수 있다
  3. 코드의 안전성과 유연성을 높일 수 있다
    • 확장 적용을 제한함으로써, 잘못된 타입에 기본 구현이 적용되지 않도록 방지할 수 있다
  4. 코드의 재사용성을 극대화할 수 있다
    • 기본 구현을 제공하되, 필요에 따라 특정 조건을 만족하는 타입에서만 적용되도록 설정할 수 있다

요약(조건부 확장의 핵심 개념)

  • Self 는 프로토콜 확장에서 확장이 적용될 타입 자신을 의미한다
  • where 절을 사용하여 프로토콜 확장을 제한할 수 있는 기능이다
  • 특정 프로토콜을 채택한 타입에서만 확장이 적용되도록 설정할 수 있다
  • 기본 구현을 제공하면서도 적용 범위를 세밀하게 제어할 수 있다
  • 잘못된 타입에 적용되는 것을 방지하여 코드의 안정성을 높일 수 있다
  • 프로토콜 지향 프로그래밍의 유연성과 재사용성을 극대화할 수 있다
profile
iOS 개발자 지망생

0개의 댓글