🔥 제네릭 함수

348자
4분

제네릭 함수는 어떤 타입과도 함께 동작할 수 있는 유연한 함수입니다. 앞서 살펴본 swapTwoInts(_:_:) 함수의 제네릭 버전인 swapTwoValues(_:_:) 함수를 살펴보겠습니다:

swift
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a // 임시 변수에 a의 값을 저장합니다.
    a = b // b의 값을 a에 할당합니다.
    b = temporaryA // 임시 변수에 저장된 a의 원래 값을 b에 할당합니다.
}
swift
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a // 임시 변수에 a의 값을 저장합니다.
    a = b // b의 값을 a에 할당합니다.
    b = temporaryA // 임시 변수에 저장된 a의 원래 값을 b에 할당합니다.
}

swapTwoValues(_:_:) 함수의 본문은 swapTwoInts(_:_:) 함수의 본문과 동일합니다. 그러나 swapTwoValues(_:_:) 의 첫 번째 줄은 swapTwoInts(_:_:) 와 약간 다르죠. 첫 번째 줄을 비교해 보겠습니다:

swift
func swapTwoInts(_ a: inout Int, _ b: inout Int)
func swapTwoValues<T>(_ a: inout T, _ b: inout T)
swift
func swapTwoInts(_ a: inout Int, _ b: inout Int)
func swapTwoValues<T>(_ a: inout T, _ b: inout T)

제네릭 버전의 함수는 실제 타입 이름(Int, String, Double 등) 대신 플레이스홀더 타입 이름(T)을 사용합니다. 플레이스홀더 타입 이름은 T 가 무엇이어야 하는지에 대해 아무것도 말해주지 않지만, abT 가 나타내는 것이 무엇이든 간에 같은 타입 T 이어야 한다는 것을 알려줍니다. swapTwoValues(_:_:) 함수가 호출될 때마다 T 대신 사용할 실제 타입이 결정됩니다.

제네릭 함수와 일반 함수의 또 다른 차이점은 제네릭 함수의 이름(swapTwoValues(_:_:)) 뒤에 꺾쇠 괄호(<T>) 안에 플레이스홀더 타입 이름(T)이 있다는 것입니다. 대괄호는 Swift에게 TswapTwoValues(_:_:) 함수 정의 내에서 플레이스홀더 타입 이름이라는 것을 알려줍니다. T 는 플레이스홀더이기 때문에 Swift는 T 라는 실제 타입을 찾지 않습니다.

이제 swapTwoValues(_:_:) 함수는 swapTwoInts 와 같은 방식으로 호출할 수 있지만, 두 값이 서로 같은 타입인 한 모든 타입의 두 값을 전달할 수 있습니다. swapTwoValues(_:_:) 가 호출될 때마다 T 에 사용할 타입은 함수에 전달된 값의 타입에서 추론됩니다.

아래의 두 예제에서 T 는 각각 IntString 으로 추론됩니다:

swift
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt는 이제 107이고, anotherInt는 이제 3입니다.
 
 
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString은 이제 "world"이고, anotherString은 이제 "hello"입니다.
swift
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt는 이제 107이고, anotherInt는 이제 3입니다.
 
 
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString은 이제 "world"이고, anotherString은 이제 "hello"입니다.

제네릭 함수를 사용하면 코드 중복을 줄이면서도 함수의 유연성을 높일 수 있습니다. 예를 들어, 정수뿐만 아니라 문자열, 부동 소수점 수 등 다양한 타입의 값을 교환하는 데 swapTwoValues(_:_:) 함수를 사용할 수 있죠.

다음 도표는 제네릭 함수의 장점을 잘 보여줍니다:

lecture image

제네릭은 Swift 프로그래밍의 강력한 기능 중 하나로, 코드의 재사용성과 유지보수성을 크게 향상시켜 줍니다. 제네릭 함수를 잘 활용하면 더 간결하고 표현력 있는 코드를 작성할 수 있을 것입니다.

YouTube 영상

채널 보기
모듈과 프로바이더 | NestJS 가이드
합타입 + 곱타입 = 강력한 타입 시스템? 대수적 데이터 타입의 비밀 | 프로그래머를 위한 카테고리 이론
NestJS 프로바이더와 @Injectable 데코레이터 | NestJS 가이드
Haskell로 배우는 Writer 모나드 | 클라이슬리 카테고리 마지막편 | 프로그래머를 위한 카테고리 이론
사이드 이펙트를 가진 함수를 합성할 수 있을까? | 클라이슬리 카테고리 1편 | 프로그래머를 위한 카테고리 이론
동적 모듈 이해하기 | NestJS 가이드
합타입 - Either, Maybe, List | 프로그래머를 위한 카테고리 이론
생성자 지옥에서 벗어나는 DI 방법 | NestJS 가이드