안녕하세요 Swift에서 반드시 알아야 하는 Function Type에 대해 알아보겠습니다. Java에서는 알지 못하다가 Swift를 하며 알게된 개념 중 하나가 Function Type입니다. Integer type, String type과 같은 "type"이지만, 모양이 독특해서 생소하게 느껴졌습니다.
Int type의 상수를 선언할 때는 아래와 같이 작성하면 됩니다.
let myInt: Int = 10
Function type은 아래와 같이 생겼습니다.
1. () -> Void
2. (Int) -> Int
3. (String, String) -> Bool
위의 예시들이 모두 Function Type입니다. 1번은 parameter도 return value도 없는 형태의 function을 의미합니다. 2번은 Int type parameter가 하나 필요하고 return value도 Int type인 function 입니다. 3번은 String type parameter 2개를 받고 Bool type을 return하는 function 입니다. 설명을 듣고 보면 그렇구나 싶은데, 처음에는 생소하기도 하고 전체 function 속에서 보면 좀 가독성이 떨어지는 것 같습니다.
🏷 가독성이 좋지는 못하다보니 typealias를 사용해서 function type에 이름을 붙여서 사용하기도 하는 것 같습니다.
예를 들어서, ```typealias VoidVoidFunction = () -> Void ``` 처럼 VoidVoidFunction이라는 이름으로 () -> Void를 의미할 수 있도록 합니다. 그런다음 () -> Void 를 사용할 부분에 VoidVoidFunction을 이용하는 것입니다. 그렇게 하면 조금 코드가 깔끔해 보이더라구요.
func firstFunc() {}
func secondFunc() {}
func thirdFunc() {}
Function Type도 상수나 변수에 할당할 수 있습니다.
// () -> Void 타입의 function 선언
func someFunc() {
print("Some Void -> Void function called")
}
// 상수에 function 할당
let myFunc: () -> Void = someFunc //someFunc뒤에 ()는 붙여주지 않아도 됩니다.
// => 이렇게 하면 myFunc는 someFunc를 "참조"합니다.
// 그리고 someFunc를 호출하는 것처럼 myFunc도 호출할 수 있습니다. ()를 붙여주면 호출이 됩니다.
Int type의 상수나 변수에는 Int 범위의 어떤 숫자던 들어갈 수 있듯이, () -> Void 라는 function type의 변수나 상수에는 () -> Void 형태이기만 하면 어떤 함수도 들어갈 수 있습니다.
이러한 Function Type은 let이나 var로 참조할 수도 있습니다. 예를 들어, 아래와 같이 작성할 수 있습니다.
var someType: () -> Void?
someType이라는 변수로는 () -> Void type인 모든 function들을 참조할 수 있습니다.
func firstFunc() {}
func secondFunc() {}
func thirdFunc() {}
someType = firstFunc
someType = secondFunc
someType = thirdFunc
firstFunc, secondFunc와 thirdFunc 모두 () -> Void type이기 때문에 셋 다 someType으로 참조가 가능합니다.
한가지 더 신기한 것은, 위와 같이 function을 참조하는 상수나 변수는 일반 function처럼 call이 가능합니다. someType() 이런 식으로요.
예시를 하나 더 들면, 아래와 같은 경우도 있을 수 있습니다.
var someOtherType: (Double, Double) -> Doube?
func someOtherFunc(x: Double, y: Double) -> Double {
return x * y
}
someOtherType = someOtherFunc
이 경우는 someOtherType은 Double type 두개를 parameter로 가지며 Double type을 return하는 function을 모두 참조할 수 있습니다. 역시 someOtherType은 function처럼 호출이 가능합니다. someOtherType(2.3, 7.2)로 호출하면 2.3 * 7.2가 계산된 값을 return 합니다.
이런 Function Type은 상수와 변수의 type으로도, parameter의 type으로 그리고 return type으로도 사용될 수 있습니다. 이렇게 여러 장소에 사용될 수 있는 특성 때문에 function을 "1st class citizen"이라고 부르기도 합니다. "어디든 갈 수 있다"는 권리가 있다는 의미입니다.
얘기가 나온 김에 return type이 function인 경우도 살펴보겠습니다.
func functionTypeReturn(x: Int) -> (Int) -> Int {
func innerFunc(y: Int) -> Int {
return x + y
}
return innerFunc
}
위 function의 return type은 (Int) -> Int 의 function입니다.
let mid:(Int) -> Int = functionTypeReturn(x: 5)
let result: Int = mid(2)
//result = 7
각 값을 상수에 할당하면 위와 같이 나타낼 수 있습니다.
왜 Function type을 사용하는 걸까?
일단 어느 정도 function type에 대해서는 알겠는데, 왜 function type을 사용하는 건지 알아보겠습니다. 이건 function 안에서 또 다른 function을 호출하는 경우를 생각해보면 이해하기 쉬운 것 같습니다.
func inner(x: Int) -> Int {
return x + 10
}
func outer(y: Int) -> Int {
let temp = inner(x: y)
return temp
}
위의 예제에서는 outer function 안에서 inner function이 사용되었습니다. 그런데 만약에 x+10이 아니라 x+11을 return 하는 function을 outer function 안에서 사용하고 싶다면, 또 다른 inner2라는 function을 만들어야 하고 outer 내부에서 호출하는 function 이름도 변경해주어야 해서 번거롭습니다.
대신에 function의 parameter 중 하나로서 function을 사용하면 이런 번거로움이 해결됩니다.
func myFuncWithFuncParam(a: Int, b: (Int) -> Int) -> Int {
return b(a)
}
이렇게 parameter로 function을 넘겨주는 형태를 쓰면 b라는 parameter에 들어올 function이 (Int) -> Int type이기만 하면되고, myFuncWithFuncParam이라는 function은 변경할 필요가 없게 됩니다.
이러한 형태는 사용할 재료와 작업도구(다른 function)을 같이 넘겨주는 것이라고 볼 수 있겠습니다.
결국 Function Type을 사용하는 이유를 정리해 보자면:
1. 간결한 코드를 작성할 수 있다: 연관된 function들을 parameter로 넘기거나 return 하면서 여러 함수로 나누어 처리하던 과정을 하나의 function에 담을 수 있게 됩니다.
2. 복합적인 처리에 유리하다: 복합적인 처리를 할 대 모든 parameter가 다 들어오길 기다리기 보다는 먼저 들어온 parameter로 특정 연산을 수행하고, 그 다음으로 들어온 parameter로 또 다른 연산을 수행하여 좀 더 효율적인 코드를 작성할 수 있다고 합니다. (return type이 function type인 경우에)
이렇게 Function Type에 대해서 알아보았습니다. 아직 조금 헷갈리기도 하지만, 사용하다보면 금새 익숙해질 것 같습니다 :)
보충할 내용이 있으면 계속해서 추가하겠습니다.
감사합니다🐥
참고자료
https://www.youtube.com/watch?v=BoFqIAywRRg
https://medium.com/@GanChau/function-types-with-swift-cedd0a805249
Function Types with Swift
Function types can be treated like any other types in Swift, such as integers and arrays. It can be defined as a constant or a variable…
medium.com
'Swfit' 카테고리의 다른 글
| Closure를 사용한 UI element 생성하기 (0) | 2022.10.19 |
|---|---|
| Array 생성하는 방법과 기본 기능들 (0) | 2022.10.18 |
| Light, dark 모드 별 사용될 backgroundimage 설정하기 (0) | 2022.10.07 |
| Observed property: willSet & didSet (0) | 2022.10.04 |
| Computed property - get, set 알아보기! (0) | 2022.09.30 |