본문 바로가기
⌨️ Language/swift

[Swift] 제네릭

by hyebin (Helia) 2024. 4. 2.

제네릭(Generics)

유연하고 재사용 가능한 함수와 타입의 코드를 작성하는 것을 가능하게 함

인자값의 타입만 다르고 동일한 기능을 수행하는 함수를 하나로 만들 수 있음

 

제네릭 함수(Generic Functions)

함수명 뒤에 타입 이름 placeholder인 T를 선언하고 a,b 파라미터를 T로 선언

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt is now 107, and anotherInt is now 3

var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString is now "world", and anotherString is now "hello"

 

타입 파라미터(Type Parameters)

placeholder 타입의 이름을 명시하고 함수명 바로 뒤에 적어준 후 꺽쇄로 묶어 사용

파라미터 이름 짓기

element 간의 상관관계가 있는 경우 의미 있는 이름을 마라미터 이름으로 사용

그렇지 않은 경우 T, U, V와 같은 단일 문자를 파라미터 이름으로 사용

 

제네릭 타입

제네릭 함수에 추가로 제네릭 타입 정의 가능

익스텐션을 이용해 제네릭 타입을 확장할 수 있음

struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}

extension Stack {
    var topItem: Element? {
        return items.isEmpty ? nil : items[items.count - 1]
    }
}

 

타입 제한

특정 타입이 반드시 어떤 프로토콜을 따라야하는 경우 특정 클래스를 상속하거나, 특정 프로토콜을 따르거나 합성하도록 명시 가능

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
    // function body goes here
}

 

연관 타입

프로토콜의 일부분으로 타입에 placeholder 이름을 부여

특정 타입을 동적으로 지정해 사용 가능

protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}

struct Stack<Element>: Container {
    // original Stack<Element> implementation
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
    // conformance to the Container protocol
    mutating func append(_ item: Element) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
}

 

제네릭의 Where절

기본 제네릭, 제네릭의 익스텐션, 연관타입, 서브스크립트에서도 where 구문을 사용해 조건을 걸 수 있음

func allItemsMatch<C1: Container, C2: Container>
    (_ someContainer: C1, _ anotherContainer: C2) -> Bool
    where C1.Item == C2.Item, C1.Item: Equatable {

        // Check that both containers contain the same number of items.
        if someContainer.count != anotherContainer.count {
            return false
        }

        // Check each pair of items to see if they're equivalent.
        for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }

        // All items match, so return true.
        return true
}
반응형

'⌨️ Language > swift' 카테고리의 다른 글

[Swift] 자동 참조 카운트  (0) 2024.04.02
[Swift] 프로토콜  (0) 2024.03.29
[Swift] 에러 처리  (0) 2024.03.28
[Swift] 옵셔널 체이닝  (0) 2024.03.26
[Swift] 초기화  (1) 2024.03.25

댓글