🔥 함수 타입
Swift에서 모든 함수는 특정한 함수 타입
을 가지고 있습니다. 함수 타입은 함수의 매개변수 타입과 반환 타입으로 구성됩니다.
예를 들어, 다음과 같은 두 개의 간단한 수학 함수가 있다고 해볼까요?
func addTwoInts(_ a: Int, _ b: Int) -> Int { return a + b } func multiplyTwoInts(_ a: Int, _ b: Int) -> Int { return a * b }
swift
addTwoInts
함수와 multiplyTwoInts
함수는 각각 두 개의 Int
값을 받아서, 적절한 수학 연산을 수행한 결과인 Int
값을 반환하죠.
이 두 함수의 타입은 (Int, Int) -> Int
입니다. 이는 다음과 같이 읽을 수 있습니다:
"두 개의 Int
타입 매개변수를 가지고, Int
타입 값을 반환하는 함수"
매개변수와 반환 값이 없는 함수도 살펴볼게요:
func printHelloWorld() { print("hello, world") }
swift
이 함수의 타입은 () -> Void
이죠. 즉, "매개변수가 없고, Void
를 반환하는 함수"라고 할 수 있겠네요.
함수 타입 사용하기
Swift에서 함수 타입은 다른 타입과 마찬가지로 사용할 수 있습니다. 예를 들어, 상수나 변수를 함수 타입으로 정의하고 적절한 함수를 해당 변수에 할당할 수 있죠:
var mathFunction: (Int, Int) -> Int = addTwoInts
swift
이는 다음과 같이 읽을 수 있어요:
"mathFunction
이라는 변수를 정의하는데, 이 변수는 '두 개의 Int
값을 받아서 Int
값을 반환하는 함수' 타입이다. 이 새로운 변수가 addTwoInts
함수를 참조하도록 설정한다."
addTwoInts(_:_:)
함수는 mathFunction
변수와 동일한 타입을 가지므로, 이 할당은 Swift의 타입 검사기에 의해 허용됩니다.
이제 mathFunction
이름으로 할당된 함수를 호출할 수 있습니다:
print("Result: \(mathFunction(2, 3))") // "Result: 5" 출력
swift
동일한 매칭 타입을 가진 다른 함수를 같은 변수에 할당할 수도 있죠. 이는 함수가 아닌 타입에서와 동일한 방식으로 동작합니다:
mathFunction = multiplyTwoInts print("Result: \(mathFunction(2, 3))") // "Result: 6" 출력
swift
다른 타입과 마찬가지로, 함수를 상수나 변수에 할당할 때 Swift가 함수 타입을 유추하도록 할 수도 있습니다:
let anotherMathFunction = addTwoInts // anotherMathFunction은 (Int, Int) -> Int 타입으로 유추됨
swift
함수 타입을 매개변수 타입으로 사용하기
(Int, Int) -> Int
와 같은 함수 타입을 다른 함수의 매개변수 타입으로 사용할 수 있습니다. 이를 통해 함수 호출 시 함수의 구현 일부를 호출자가 제공하도록 할 수 있죠.
위의 수학 함수 결과를 출력하는 예제를 살펴볼까요?
func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) { print("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) // "Result: 8" 출력
swift
이 예제는 printMathResult(_:_:_:)
라는 함수를 정의하는데, 이 함수는 세 개의 매개변수를 가집니다. 첫 번째 매개변수는 mathFunction
이라고 하며, (Int, Int) -> Int
타입입니다. 이 첫 번째 매개변수에 해당 타입의 모든 함수를 인자로 전달할 수 있죠. 두 번째와 세 번째 매개변수는 a
와 b
라고 하며, 둘 다 Int
타입입니다. 이들은 제공된 수학 함수에 대한 두 개의 입력 값으로 사용됩니다.
printMathResult(_:_:_:)
가 호출되면, addTwoInts(_:_:)
함수와 정수 값 3
과 5
가 전달됩니다. 그리고 제공된 함수를 값 3
과 5
로 호출하고, 결과 8
을 출력하죠.
printMathResult(_:_:_:)
의 역할은 적절한 타입의 수학 함수 호출 결과를 출력하는 것입니다. 해당 함수의 실제 구현이 어떻게 되는지는 중요하지 않아요. 단지 함수가 올바른 타입이라는 것만 중요하죠. 이를 통해 printMathResult(_:_:_:)
는 타입 안전한 방식으로 함수의 일부 기능을 함수 호출자에게 넘길 수 있습니다.
함수 타입을 반환 타입으로 사용하기 (Function Types as Return Types)
함수 타입을 다른 함수의 반환 타입으로 사용할 수도 있습니다. 이를 위해서는 반환하는 함수의 반환 화살표(->
) 바로 뒤에 전체 함수 타입을 작성하면 됩니다.
다음 예제는 stepForward(_:)
와 stepBackward(_:)
라는 두 개의 간단한 함수를 정의합니다. stepForward(_:)
함수는 입력 값보다 1 큰 값을 반환하고, stepBackward(_:)
함수는 입력 값보다 1 작은 값을 반환하죠. 두 함수 모두 (Int) -> Int
타입을 가집니다:
func stepForward(_ input: Int) -> Int { return input + 1 } func stepBackward(_ input: Int) -> Int { return input - 1 }
swift
다음은 chooseStepFunction(backward:)
이라는 함수인데, 이 함수의 반환 타입은 (Int) -> Int
입니다. chooseStepFunction(backward:)
함수는 backward
라는 Bool 매개변수에 따라 stepForward(_:)
함수 또는 stepBackward(_:)
함수를 반환합니다:
func chooseStepFunction(backward: Bool) -> (Int) -> Int { return backward ? stepBackward : stepForward }
swift
이제 chooseStepFunction(backward:)
을 사용하여 한 방향 또는 다른 방향으로 이동하는 함수를 얻을 수 있습니다:
var currentValue = 3 let moveNearerToZero = chooseStepFunction(backward: currentValue > 0) // moveNearerToZero는 이제 stepBackward() 함수를 참조함
swift
위의 예제는 currentValue
라는 변수를 점진적으로 0에 가깝게 이동시키기 위해 양의 단계 또는 음의 단계가 필요한지 결정합니다. currentValue
의 초기 값은 3
이므로, currentValue > 0
은 true
를 반환하고, 이로 인해 chooseStepFunction(backward:)
은 stepBackward(_:)
함수를 반환하죠. 반환된 함수에 대한 참조는 moveNearerToZero
라는 상수에 저장됩니다.
이제 moveNearerToZero
가 올바른 함수를 참조하므로, 이를 사용하여 0까지 셀 수 있습니다:
print("Counting to zero:") // "Counting to zero:" 출력 while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } print("zero!") // 3... // 2... // 1... // "zero!" 출력
swift
이처럼 Swift에서는 함수 타입을 다양한 방식으로 활용할 수 있습니다. 함수를 변수나 상수에 할당하고, 함수의 매개변수로 전달하며, 함수에서 함수를 반환할 수도 있죠. 이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다.
함수 타입에 대해 더 자세히 알아보니 흥미롭지 않나요? 함수형 프로그래밍의 핵심 개념 중 하나인 '일급 함수(first-class function)'를 Swift에서도 지원한다는 것을 알 수 있었어요. 함수를 값처럼 다룰 수 있다는 것은 정말 강력한 기능이라고 생각합니다.