🔥 제네릭이 해결하는 문제
제네릭은 Swift 프로그래밍에서 매우 강력하고 유용한 기능 중 하나입니다. 제네릭을 사용하면 코드의 재사용성과 유연성을 크게 향상시킬 수 있죠. 그럼 제네릭이 어떤 문제를 해결하는지 자세히 살펴볼까요?
먼저, 두 개의 Int
값을 서로 교환하는 swapTwoInts(_:_:)
함수를 살펴봅시다:
func swapTwoInts(_ a: inout Int, _ b: inout Int) { let temporaryA = a // a의 값을 temporaryA에 임시 저장 a = b // b의 값을 a에 할당 b = temporaryA // temporaryA의 값(원래 a의 값)을 b에 할당 }
swift
이 함수는 inout
매개변수를 사용하여 a
와 b
의 값을 교환합니다. inout
매개변수에 대한 자세한 설명은 In-Out Parameters에서 확인할 수 있습니다.
swapTwoInts(_:_:)
함수는 원래 b
의 값을 a
에 넣고, 원래 a
의 값을 b
에 넣습니다. 이 함수를 호출하여 두 개의 Int
변수의 값을 교환할 수 있습니다:
var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt) print("someInt is now \(someInt), and anotherInt is now \(anotherInt)") // "someInt is now 107, and anotherInt is now 3"이 출력됩니다.
swift
swapTwoInts(_:_:)
함수는 유용하지만, Int
값에만 사용할 수 있다는 한계가 있습니다. 만약 두 개의 String
값이나 Double
값을 교환하고 싶다면, 아래와 같이 swapTwoStrings(_:_:)
와 swapTwoDoubles(_:_:)
함수를 추가로 작성해야 합니다:
func swapTwoStrings(_ a: inout String, _ b: inout String) { let temporaryA = a a = b b = temporaryA } func swapTwoDoubles(_ a: inout Double, _ b: inout Double) { let temporaryA = a a = b b = temporaryA }
swift
swapTwoInts(_:_:)
, swapTwoStrings(_:_:)
, swapTwoDoubles(_:_:)
함수의 내용이 동일하다는 점을 눈치채셨나요? 유일한 차이점은 받아들이는 값의 타입(Int
, String
, Double
)뿐입니다.
훨씬 더 유용하고 유연한 방법은 '모든' 타입의 두 값을 교환하는 단일 함수를 작성하는 것입니다. 바로 여기서 제네릭 코드가 등장합니다. (이러한 함수의 제네릭 버전은 아래에 정의되어 있습니다.)
func swapTwoValues<T>(_ a: inout T, _ b: inout T) { let temporaryA = a // 제네릭 타입 T의 값을 temporaryA에 저장 a = b // b의 값을 a에 할당 b = temporaryA // temporaryA의 값을 b에 할당 }
swift
제네릭 함수 swapTwoValues<T>(_:_:)
는 타입 매개변수 T
를 사용하여 어떤 타입의 값이라도 교환할 수 있습니다. 이제 Int
, String
, Double
등 모든 타입에 대해 단 하나의 함수로 값 교환이 가능해졌네요.
var genericInt = 3 var genericString = "Hello" var genericDouble = 3.14 swapTwoValues(&genericInt, &anotherInt) swapTwoValues(&genericString, &"World") swapTwoValues(&genericDouble, &2.71) print(genericInt) // 107 print(genericString) // "World" print(genericDouble) // 2.71
swift
이렇게 제네릭을 사용하면 코드 중복을 제거하고, 더 유연하고 재사용 가능한 함수와 타입을 만들 수 있습니다. 제네릭은 Swift 표준 라이브러리에서 광범위하게 사용되며, 배열(Array), 딕셔너리(Dictionary), 세트(Set), 옵셔널(Optional) 등 다양한 범용 콜렉션 타입을 구현하는 데 핵심적인 역할을 합니다.