프로토콜은 어떤 메서드와 프로퍼티을 꼭 가지고 있어야하는지 설명하는 방식이다.
그런 뒤에 해당 프로토콜을 사용하는 유형을 Swift에 알려준다. – 프로터콜을 채택하거나 준수하는 것으로 알려진 과정
예를 들어, 우리는 id 프로퍼티로 받아들이는 함수를 만들 수 있지만 정확히 어떤 데이터 타입이 사용되는지 크게 상관하지 않는다.
protocol Identifiable {
Var id: String { get set}
}
우리는 이 프로토콜의 인스턴스를 만들 수는 없다 – 프로토콜은 우리가 만들고 바로 사용하는 것이라기보다 우리가 원하는 것의 묘사이다.
struct User: Identifiable {
var id: String
}
func displayID(thing: Identifiable) {
print(“My ID is \(thing.id)”)
}
하나의 프로토콜은 다른 프로세스에서 상속받을 수 있고 이것이 프로토콜 상속이다.
클래스와 달리, 사용자 정의를 추가하기 전에 한 번에 여러 프로토콜을 상속받을 수 있다.
우리는 세 개의 프로토콜을 정의할 것이다
protocol Payable {
func calculateWages() -> Int
}
protocol NeedsTraining {
func study()
}
Protocol HasVacation {
func takeVacation(days: Int)
}
Protocol Employee: Payable, NeedsTraining, HasVacation {
}
이제 새로운 타입이 세 가지 개별 프로토콜이 아니라 단일 프로토콜(Employee)만 준수하도록 하면 된다.
Extension 은 원래 존재하던 타입에 메서드를 추가하여 원래 설계되지 않은 작업을 수행하도록 한다.
extension Int {
func squared() -> Int {
return self * self
}
}
let number =. 8
number.squared()
익스텐션에 저장 프로퍼티는 추가할 수 없기 때문에 계산 프로퍼티를 사용해야한다.
extension Int {
var isEven: Bool {
return self % 2 == 0
}
}
프로토콜은 어떤 메서드를 가지고 있어야하는지 알려주지만 그 안의 코드는 제공하지 않는다.
익스텐션은 메서드 안에 코드를 작성할 수 있게 하지만 한 가지 데이터 유형에만 영향을 미친다 – 한 번에 여러 유형에다 메서드를 추가할 수는 없다.
프로토콜 익스텐션은 이러한 문제점들을 모두 해결한다
: 이들은 Int와 같은 특정 유형을 확장하는 대신 전체 프로토콜을 확장하여 모든 준수 유형들이 변경 사항을 알 수 있게 한다는 점을 제외하고는 일반 익스텐션과 같다.
let pythons = [“Eric”, “Graham”, “John”, “Michael”, “Terry”, “Terry”]
let beatles = Set([“John”, “Paul”, “George”, “Ringo”])
extension Collection {
func summarize() {
print(“There are \(count) of us:”)
for name in self {
print(name)
}
}
}
pythons.summarize()
beatles.summarize()
프로토콜 확장은 자체 프로토콜 메서드에 대한 디폴트 실행을 제공한다.
이것은 타입이 프로토콜을 더 쉽게 준수할 수 있게 하고 “protocol-oriented programming” 이라는 기술 – 프로토콜 과 프로토콜 확장을 중심으로 코드를 만드는 것 - 을 허용한다.
protocol identifiable {
var id: String { get set {
func identify()
}
extension Identifiable {
func identify() {
print(“My ID is \(id).”)
}
}
struct User: Identifiable {
var id: String
}
let twostraws = User(id: “twostraws”)
twostraws.identify()