프로토콜 확장
Coddy Swift 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 29번째.
프로토콜 확장은 프로토콜의 메서드에 기본 구현을 제공합니다. 이를 준수하는 모든 타입은 이를 무료로 사용할 수 있으며, 타입은 여전히 자체 버전을 제공할 수 있습니다:
protocol Greeter {
var name: String { get }
func greet() -> String
}
extension Greeter {
func greet() -> String { "Hello, \(name)!" }
}
struct English: Greeter { let name: String }
struct Pirate: Greeter {
let name: String
func greet() -> String { "Ahoy, \(name)!" }
}
print(English(name: "Ada").greet())
print(Pirate(name: "Ada").greet())출력:
Hello, Ada!
Ahoy, Ada!확장은 요구 사항만으로 구성된 새로운 메서드도 추가할 수 있습니다. 준수하는 타입은 필요한 작은 부분을 작성하고 나머지를 받습니다:
protocol Scored {
var points: [Int] { get }
}
extension Scored {
var total: Int { points.reduce(0, +) }
var best: Int { points.max() ?? 0 }
func summary() -> String { "total \(total), best \(best)" }
}
struct Player: Scored {
let points: [Int]
}
print(Player(points: [3, 9, 4]).summary())출력:
total 16, best 9이는 상속 없이 구조체, 클래스 및 열거형 간에 동작을 공유합니다. 표준 라이브러리도 같은 방식으로 작동합니다. 모든 Collection은 프로토콜 확장을 통해 isEmpty, first 및 map을 가져옵니다.
extension Collection {
// isEmpty, first, map, filter, ...는 모두 여기서 한 번 정의됩니다
// 그리고 모든 array, set, dictionary 및 string이 그것들을 얻습니다
}제약 확장은 where를 사용하여 특정 조건을 충족하는 타입에만 메서드를 추가합니다:
protocol Container {
associatedtype Item
var items: [Item] { get }
}
extension Container where Item == Int {
var sum: Int { items.reduce(0, +) }
}
struct Box: Container {
var items: [Int]
}
print(Box(items: [2, 5]).sum)출력:
7챌린지
쉬움Priced 프로토콜을 선언하고 var price: Int { get }(센트 단위)와 var formatted: String { get }을 요구하세요. 프로토콜 확장에서 formatted에 $4.50을 반환하는 기본 구현을 제공하고, 가격이 예산에 맞는지를 반환하는 isAffordable(budget:) 메서드를 추가하세요. Coffee(가격 450)와 Sandwich(저장된 price) 구조체가 이 프로토콜을 준수하도록 만드세요. Coffee는 기본 formatted를 coffee $4.50으로 대체해야 합니다.
제공된 코드는 예산을 읽은 다음 coffee 또는 sandwich,650 형식의 줄을 읽습니다. 각 항목에 대해 formatted와 yes 또는 no를 출력합니다.
코드는 Priced.swift, Coffee.swift, Sandwich.swift에 작성하세요. main.swift에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.
직접 해보기
// 제공된 입력/출력 코드: 있는 그대로 유지하세요
var input: [String] = []
while let line = readLine() { input.append(line) }
let budget = Int(input[0])!
for line in input.dropFirst() {
let item: any Priced = line == "coffee" ? Coffee() : Sandwich(price: Int(line.split(separator: ",")[1])!)
print("\(item.formatted) \(item.isAffordable(budget: budget) ? "yes" : "no")")
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: Swift 플레이그라운드