아리의 iOS 탐구생활

[Swift] Protocol 6) 프로토콜의 확장을 알아보자 본문

Swift/문법

[Swift] Protocol 6) 프로토콜의 확장을 알아보자

Ari Lee 2021. 8. 18. 18:29
반응형
Protocol Extension

extension은 타입을 확장한다. 프로토콜 역시 타입이기 때문에 extension을 활용하여 확장할 수 있다.

프로토콜에는 정의만 한다고 하였는데 extension을 통해 구현을 추가한다는 것이 조금 어색할 수도 있다.

정리하자면 문법적으로는 프로토콜의 구현을 추가하지만 실제로는 프로토콜을 채용한 타입의 구현이 추가된다고 보면 된다.

코드의 중복을 줄이면서 프로토콜을 확장시킬 수 있다는 장점이 있다.

예제를 통해 이해해보자.

 

protocol SayText {
    var text: String { get set }
    func say()
}

extension SayText {
    func say() {
        print(text)
    }
}

struct A: SayText {
    var text = "프로토콜 확장!"
}

let a = A()
a.say()

구조체 A에서는 프로토콜에 정의된 say()메소드를 구현하지 않았는데 에러가 없다.

확장을 통하여 say 메서드를 구현해줬기 때문에 프로토콜의 요구사항을 충족시키기 때문이다.

 

 

그러나 아래와 같이 say() 메소드를 구현해주면 확장하여 구현하였던 메소드는 무시된다.

protocol SayText {
    var text: String { get set }
    func say()
}

extension SayText {
    func say() {
        print(text)
    }
}

struct A: SayText {
    var text = "프로토콜 확장!"
    func say() {  // say 메서드 구현
        print("중복은 가볍게 무시해주지")
    }
}

let a = A()
a.say()

메서드를 직접 구현해도 중복으로 인한 에러는 발생하지 않는다.

타입에서 직접 구현한 멤버가 확장을 통해 구현한 멤버보다 높은우선순위를 가지고 있기 때문이다.

 

 

 

 

프로토콜의 확장은 프로토콜을 채택한 모든 멤버를 추가하는데, 멤버를 추가할 타입을 제한할 수도 있다.

extension SayText where Self: Equatable { // where 키워드로 타입 제한
    func say() {
        print(text)
    }
}

struct A: SayText { // Equatable을 채택하지 않았기 때문에 say 메서드를 직접 구현하지 않으면 에러가 발생한다.
    var text = "프로토콜 확장!"
}

위와 같이 타입을 제한하였는데 프로토콜만 채택하고 확장에서 제한한 타입을 같이 채택하지 않으면 확장에서 구현한 멤버도 추가되지 않는다.

 

따라서 아래와 같이 제한한 타입을 추가해주면 에러가 해결된다.

protocol SayText {
    var text: String { get set }
    func say()
}

extension SayText where Self: Equatable { // 확장하면서 타입도 추가하였다.
    func say() {
        print(text)
    }
}

struct A: SayText, Equatable { // Equatable을 추가하여 확장에서 구현한 멤버 say()가 추가되었다.
    var text = "프로토콜 확장!"
}

let a = A()
a.say()

 

 

 

 

✔️  Reference

 

Protocols — The Swift Programming Language (Swift 5.5)

Protocols A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of tho

docs.swift.org

 

반응형
Comments