[iOS 11주차] Swift: extension, where

DoyleHWorks·7일 전
0

extension, protocol, where

Swift에서 프로토콜을 확장할 때 where 절을 사용하여 특정 조건을 제약하는 방법은 매우 유용하다. 이를 통해 프로토콜 확장이 특정 타입, 제네릭 제약, 또는 프로토콜 준수 여부에 따라 적용되도록 제한할 수 있다. 아래는 다양한 예시와 활용법이다.


1. 특정 타입에 대해 확장

where 절을 사용해 특정 타입에 대해서만 확장을 제한할 수 있다.

protocol Greetable {
    func greet()
}

extension Greetable where Self: String {
    func greet() {
        print("Hello, \(self)!")
    }
}

extension String: Greetable {}

"Swift".greet() // 출력: Hello, Swift!

2. 제네릭 제약 조건 사용

제네릭을 사용하는 프로토콜의 확장을 특정 타입이나 프로토콜에 한정할 수 있다.

protocol Summable {
    func sum() -> Int
}

extension Array: Summable where Element == Int {
    func sum() -> Int {
        return self.reduce(0, +)
    }
}

let numbers = [1, 2, 3, 4]
print(numbers.sum()) // 출력: 10

3. 프로토콜 준수 여부로 제한

타입이 특정 프로토콜을 준수할 때만 확장을 적용할 수 있다.

protocol Describable {
    var description: String { get }
}

extension Array where Element: Describable {
    func describeAll() {
        for element in self {
            print(element.description)
        }
    }
}

struct Person: Describable {
    var name: String
    var description: String { return "Person: \(name)" }
}

let people = [Person(name: "Alice"), Person(name: "Bob")]
people.describeAll()
// 출력:
// Person: Alice
// Person: Bob

4. Equatable 제약을 추가한 활용

타입이 Equatable을 준수하는 경우에만 특정 기능을 제공할 수 있다.

extension Array where Element: Equatable {
    func duplicates() -> [Element] {
        var seen: Set<Element> = []
        var duplicates: [Element] = []
        for value in self {
            if seen.contains(value) {
                duplicates.append(value)
            } else {
                seen.insert(value)
            }
        }
        return duplicates
    }
}

let items = [1, 2, 3, 1, 2, 4]
print(items.duplicates()) // 출력: [1, 2]

5. Associated Type 사용

프로토콜의 연관 타입(associated type)을 기반으로 확장을 제약할 수도 있다.

protocol Container {
    associatedtype Item
    var items: [Item] { get }
}

extension Container where Item == String {
    func joinedItems() -> String {
        return items.joined(separator: ", ")
    }
}

struct StringContainer: Container {
    var items: [String]
}

let container = StringContainer(items: ["Apple", "Banana", "Cherry"])
print(container.joinedItems()) // 출력: Apple, Banana, Cherry

6. 복합 조건 사용

where 절에서 여러 조건을 조합하여 사용할 수도 있다.

protocol Sortable {}

extension Array: Sortable where Element: Comparable {}

extension Sortable where Self: Array, Element: Comparable {
    func sortedArray() -> [Element] {
        return self.sorted()
    }
}

let values = [3, 1, 4, 1, 5]
if let sortable = values as? [Int] & Sortable {
    print(sortable.sortedArray()) // 출력: [1, 1, 3, 4, 5]
}

요약

  • 특정 타입이나 프로토콜 준수 여부에 따라 조건부 확장을 정의할 수 있다.
  • 제네릭 타입associated type의 제약 조건을 활용할 수 있다.
  • 복합적인 조건을 사용하여 보다 정교한 확장을 작성할 수 있다.
profile
Reciprocity lies in knowing enough

0개의 댓글