Menu
Coddy logo textTech

프로토콜 확장

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
challenge icon

챌린지

쉬움

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")")
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: Swift 플레이그라운드