Swift Protocols

2021년 9월 6일 수정

프로토콜(Protocols)

Swift의 프로토콜 기능은 이름 처럼 약속이나 규약을 정의하는 기능이다. 직관적으로 표현하자면 클래스나 구조체 등이 지녀야 할 메서드나 프로퍼티 등을 정의하고 이를 구현하도록 유도하는 기능이다.

기본적인 사용법

프로토콜은 대충 아래와 같이 정의한다.

protocol SomeProtocol {
    var someProperty: Int { get set }
    var someReadOnlyProperty: String { get }
    func someMethod(input: String) -> String
}

프로토콜에서는 이렇게 프로퍼티나 메서드를 정의만 한다.

이를 특정 구조체나 클래스에는 아래처럼 적용할 수 있다.

struct SomeType: SomeProtocol {
    var someProperty: Int = 0
    var someReadOnlyProperty: String { return "Value" }
    func someMethod(input: String) -> String { ... }
    ...
}

class SomeClass: SomeBaseClass, SomeProtocol, AnotherProtocol {
    var someProperty: Int = 0
    var someReadOnlyProperty: String { return "Value" }
    func someMethod(input: String) -> String { ... }
    ...
}

프로토콜은 상속이 아니기 때문에 상속과는 다르게 여러 프로토콜을 적용할 수 있다. 구조체의 경우 첫 자리라도 부모 클래스가 아닌 프로토콜이 온다는 점은 클래스와 다르다.

Cheatsheet

문법을 상세히 정리하기엔 너무 귀찮고(…) 대충 치트시트로 프로토콜 정의법을 정리해보자.

protocol Something {
    init(someParameter: Int)

    var someReadOnlyProperty: String { get }
    var someWritableProperty: String { get set }
    var syncedValue: Bool { get async }
    var syncedThrwoingValue: Bool { get async throws }

    func someMethod(input: String) -> String
    static func someStaticMethod() -> Int
}

기본 기능 구현

프로토콜은 원래 정의한 하는 용도지만 필요하다면 기본 기능을 구현해 줄 수도 있다. 이 경우 extension 을 이용한다.

extension Something {
    var someReadOnlyProperty: String {
        return "Value"
    }

    static func someStaticMethod() -> Int {
        return 0
    }
}

이렇게 해두면 미리 구현된 프로퍼티나 메서드는 따로 구현하지 않으면 기본 구현된 내용이 사용된다.

특정 클래스 전용 프로토콜

아래 프로토콜은 SomeType 이라는 클래스에서만 정의할 수 있게 선언된다.

protocol SomeGoodType where Self: SomeType {
    ...
}

비슷하게 extension 을 이용해 특정 클래스 전용으로 구현할 수도 있다.

extension SomeGoodType where Self: SomeType {
    ...
}