# [Swift] Nested function

기존의 C, C++에서는 함수안에서 다른 함수를 호출하는 것이 일반적이었습니다. 그러나 Swift에서는 함수 안에 함수를 넣어 구현을 할 수 있습니다. Swift에서 특별한 위치에 속해 있지 않는 한 모두 전역 함수인데 비해 함수 안에 구현된 중첩함수는 함수 안에서만 사용 가능합니다 (반환하면 밖에서도 사용 가능). 특히 전역함수가 많은 프로그램에서는 중첩함수를 이용하면 함수 사용범위를 좀 더 명확하게 표현해줄 수 있는 장점을 가집니다.

  • Swift 는 함수 내부에 또 다른 함수 생성 가능 (중첩함수)
  • 내부의 중첩된 함수는 바깥쪽 함수에 선언된 변수를 사용할 수 있다. (물론 외부함수의 인자에도 접근 가능)
  • 중첩함수의 호출은 함수 내부에서만 가능하다. ==> 내부적으로 은닉 가능.
  • 내부함수는 외부함수가 실행되는 순간 생성되고, 종료되는 순간 소멸된다.
  • 외부함수를 호출했을 때 내부함수를 반환하여 외부에서 사용하는 것도 가능하다.

출처: https://nightohl.tistory.com/entry/Swift-중첩함수 [Till Done sTeal Dawn]

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0

    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }

    return incrementer
}

makeIncrementer의 반환 타입은 () -> Int 입니다! 이것은 간단한 값을 리턴하는 것이 아닌 함수 객체를 리턴한다는 의미입니다! 이 함수는 파라미터를 가지지 않으며 호출될 때마다 Int의 값을 리턴하게 됩니다. makeIncrementer 함수는 incrementer()를 수행하는 중첩 함수를 리턴하게 됩니다!

let incrementByTen = makeIncrementer(forIncrement: 10)

print(incrementByTen()) // 10
print(incrementByTen()) // 20
print(incrementByTen()) // 30


let incrementBySeven = makeIncrementer(forIncrement: 7)

내부의 중첩된 함수는 바깥쪽 함수에 선언된 변수를 사용할 수 있다. (물론 외부함수의 인자에도 접근 가능) 이 부분덕분에, 값이 바뀐것을 확인할 수 있다.

위와 같이 incrementer를 하나 더 생성하더라도 incrementByTen과는 별개로 다른 참조를 갖는 runningTotal 프로퍼티가 생기기 때문에 서로 영향을 받지 않게 됩니다! 이는 각각 자신의 runningTotal의 참조를 미리 획득했기 때문입니다!

// 중첩 함수

typealias UpDownFunc = (Int) -> Int			// 타입 별칭

func funcForMove(shouldGoUP: Bool) -> UpDownFunc {	// 반환 타입이 함수
    
    func goUp(currentFloor: Int) -> Int {
        return currentFloor + 1
    }
    
    func goDown(currentFloor: Int) -> Int {
        return currentFloor - 1
    }
    
    return shouldGoUP ? goUp : goDown
}

var currentFloor: Int = 10

var targetFloor: Int = 6

let moveToTarget: UpDownFunc = funcForMove(shouldGoUP: currentFloor<targetFloor)

while currentFloor != targetFloor {
    print("현재 \(currentFloor) 층...")
    currentFloor = moveToTarget(currentFloor)
}

print("띵! \(currentFloor)층 도착.")