🔥 프로토콜과 익스텐션
Swift에서는 protocol
을 사용하여 프로토콜을 선언할 수 있습니다. 프로토콜은 특정 작업이나 기능에 적합한 메서드, 프로퍼티 등을 요구사항으로 정의합니다. 그리고 이 요구사항을 실제로 구현하는 것은 프로토콜을 채택한 타입의 역할이에요.
예를 들어, 다음과 같이 ExampleProtocol
프로토콜을 정의해 보겠습니다.
protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() }
swift
위 코드에서는 simpleDescription
이라는 읽기 전용 프로퍼티와 adjust()
라는 메서드를 요구사항으로 정의하고 있어요.
이제 클래스, 열거형, 구조체는 모두 이 프로토콜을 채택할 수 있습니다. 아래 코드를 살펴볼까요?
class SimpleClass: ExampleProtocol { var simpleDescription: String = "A very simple class." var anotherProperty: Int = 69105 func adjust() { simpleDescription += " Now 100% adjusted." } } var a = SimpleClass() a.adjust() let aDescription = a.simpleDescription
swift
SimpleClass
는 ExampleProtocol
을 채택하고 있으며, 프로토콜에서 요구한 프로퍼티와 메서드를 모두 구현하고 있습니다.
이번에는 구조체에서 프로토콜을 채택하고 사용하는 예시를 살펴보겠습니다.
struct SimpleStructure: ExampleProtocol { var simpleDescription: String = "A simple structure" mutating func adjust() { simpleDescription += " (adjusted)" } } var b = SimpleStructure() b.adjust() let bDescription = b.simpleDescription
swift
구조체에서 프로토콜을 채택할 때, 구조체 내부의 프로퍼티를 변경하는 메서드 앞에는 mutating
키워드를 붙여줘야 해요. 반면에 클래스의 경우에는 이 키워드가 필요 없답니다.
또한 Swift에서는 extension
을 사용하여 기존 타입에 기능을 추가할 수도 있어요. 이를 통해 메서드, 계산 프로퍼티 등을 추가로 구현할 수 있죠. 심지어 이미 존재하는 타입이 특정 프로토콜을 준수하도록 확장할 수도 있습니다.
extension Int: ExampleProtocol { var simpleDescription: String { return "The number \(self)" } mutating func adjust() { self += 42 } } print(7.simpleDescription) // "The number 7" 출력
swift
위 코드에서는 Int
타입이 ExampleProtocol
을 채택하도록 확장했어요. 이제 Int
타입에서도 simpleDescription
프로퍼티와 adjust()
메서드를 사용할 수 있게 되었답니다.
프로토콜은 마치 하나의 타입처럼 사용될 수도 있어요. 예를 들어, 서로 다른 타입이지만 같은 프로토콜을 준수하는 객체들의 컬렉션을 만들 수 있죠.
let protocolValue: any ExampleProtocol = a print(protocolValue.simpleDescription) // "A very simple class. Now 100% adjusted." 출력 // print(protocolValue.anotherProperty) // 주석을 제거하면 에러 발생
swift
protocolValue
변수는 ExampleProtocol
프로토콜을 준수하는 어떤 타입이든 참조할 수 있어요. 하지만 해당 프로토콜에 정의되지 않은 메서드나 프로퍼티는 사용할 수 없답니다.