제네릭

JG Ahn·2024년 11월 8일

swift 심화

목록 보기
8/18
post-thumbnail

제네릭이란?

함수나 타입을 정의할 때 구체적인 데이터 타입을 명시하지 않고, 나중에 사용하는 시점에서 타입을 지정할 수 있게 해주는 기능

  • 제네릭을 사용하면 Swift에서 다양한 타입에 대한 유연하고 재사용 가능한 코드를 작성할 수 있음
  • 중복 코드를 줄이고, 명확하고 추상적인 방식으로 코드를 표현 가능
  • 제네릭을 사용하면 하나의 함수, 구조체, 클래스, 열거형 등이 여러 타입에서 작동할 수 있도록 만들 수 있음
  • < > 안에 있는 이름이 범용으로 사용할 타입의 이름이며, 나중에 사용할 때 구체적인 타입이 정해짐

함수에서 사용하는 경우

// 두 값을 비교하는 제네릭 함수
// 제네릭 타입을 정하지 않고 T 로 만들어 나중에 어떤 타입이든 받을 수 있도록 처리
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var a = 10
var b = 20
swapTwoValues(&a, &b)
print("a: \(a), b: \(b)") // a: 20, b: 10

var x = "Hello"
var y = "World"
swapTwoValues(&x, &y)
print("x: \(x), y: \(y)") // x: World, y: Hello

구조체에서 사용하는 경우

struct Stack<Element> {
    var items: [Element] = []

    mutating func push(_ item: Element) {
        items.append(item)
    }

    mutating func pop() -> Element? {
        return items.popLast()
    }
}

var intStack = Stack<Int>() //스택을 만드는 순간 타입이 정해짐
intStack.push(10)
intStack.push(20)
print(intStack.pop()!) // 20

var stringStack = Stack<String>() //스택을 만드는 순간 타입이 정해짐
stringStack.push("Hello")
stringStack.push("World")
print(stringStack.pop()!) // World

제네릭 제약

  • 제네릭은 모든 타입에 대해 작동할 수 있지만, 특정 조건을 부여하여 제약을 걸 수 있음
  • 특정 프로토콜을 준수하거나, 특정 클래스의 하위 클래스에서만 허용 할 수 있음
// 프로토콜 Comparable을 준수하는 타입만 허용하도록 제네릭 설정 (방식 1)
func findMinimumValue2<T>(array: [T]) -> T? where T : Comparable {
    guard !array.isEmpty else { return nil }
    return array.min()
}

// 프로토콜 Comparable을 준수하는 타입만 허용하도록 제네릭 설정 (방식 2)
func findMinimumValue<T: Comparable>(in array: [T]) -> T? {
    guard !array.isEmpty else { return nil }
    return array.min()
}

let intArray = [3, 1, 4, 1, 5, 9]
if let minValue = findMinimumValue(in: intArray) {
    print("Minimum value: \(minValue)") // Minimum value: 1
}

let stringArray = ["Apple", "Banana", "Cherry"]
if let minValue = findMinimumValue(in: stringArray) {
    print("Minimum value: \(minValue)") // Minimum value: Apple
}

0개의 댓글