함수타입
: 변수에 함수를 대입하면 그 변수는 함수 타입이 된다.
(함수 타입은 함수의 형태를 축약한 형태로 사용한다.)
// 정수를 입력받는 함수
func foo(base: Int) -> String {
return "결과값은 \(base + 1)입니다"
}
let fn1 = foo(base: 5)
// 결과값은 6입니다
let fn2 = foo // fn2 상수에 foo 함수가 할당됨
fn2(5) // 결과값은 6입니다
(인자 타입1, 인자 타입2, ...) -> 반환 타입
func boo(age: Int) -> String {
return "\(age)"
}
// 위 함수 타입
(Int) -> String
// 상수에 할당
1. let fn: (Int) -> String = boo
2. let fn: (Int) -> String = boo(age:)
func boo(age: Int, name: String) -> (String, Int) {
return (name, age)
}
// 위 함수 타입
(Int, String) -> (String, Int)
func boo() -> String {
return "empty values"
}
// 위 함수 타입
() -> String
func boo(base: Int) {
print("param = \(base)")
}
// 위 함수 타입
(Int) -> ()
// 반환값이 없을 때는 Void라고 표현 가능 (인자값은 안됨)
(Int) -> () => (Int) -> Void
() -> () => () -> Void
func plus(a: Int, b: Int) -> Int {
return a + b
}
func minus(a: Int, b: Int) -> Int {
return a - b
}
func times(a: Int, b: Int) -> Int {
return a * b
}
func divide(a: Int, b: Int) -> Int {
guard b != 0 else {
return 0
}
return a / b
}
func calc(_ operand: String) -> (Int, Int) -> Int {
switch operand {
case "+" :
return plus
case "-" :
return minus
case "*" :
return times
case "/" :
return divide
default :
return plus
}
}
let c = calc("+")
c(3,4) // plus(3,4) = 7
let c2 = calc("-")
c2(3,4) // minus(3,4) = -1
let c3 = calc("*")
c3(3,4) // times(3,4) = 12
let c4 = calc("/")
c4(3,4) // divide(3,4) = 0
func incr(param: Int) -> Int {
return param + 1
}
func broker(base: Int, function: (Int) -> Int) -> Int {
return function(base)
}
broker(base: 3, function: incr) // 4
function
이라는 파라미터
는 정수를 파라미터로 받아 정수를 리턴하는 함수
다.
실질적인 연산은 인자로 받는 함수에 달려 있기 때문에 broker(base:function:) 함수의 정의 구문만으로는 어떤 연산이 실행될지 짐작하기 어렵다.
이런 식으로 중개 역할을 하는 함수를 브로커(Broker)
라고 한다.
외부 함수
: 내부 함수를 포함하는 바깥쪽 함수
내부 함수
: 함수 내에 작성된 함수는 내부 함수, 일반적으로 외부 함수를 거치지않으면 접근불가능하다 (함수의 은닉성)
💡 내부 함수 생명 주기(Life Cycle)
외부 함수가 종료되면 내부 함수도 종료된다. (함수 내에 작성할 수 있는 내부 함수 수는 제한이 없다.)
// 외부 함수
func outer(base: Int) -> String {
// 내부 함수
func inner(inc: Int) -> String {
return "\(inc)를 반환합니다"
}
let result = inner(inc: base + 1)
return result
}
outer(base: 3)
// "4를 반환합니다"
// inner라는 함수는 outer라는 함수를 통해서만 접근 가능
// 내부 함수는 외부 함수가 실행되면서 내부 함수에 대한 참조가 발생하면 생성
// 외부 함수가 종료되면서 내부 함수에 대한 참조도 종료되면 내부 함수는 소멸
// 외부 함수
func outer(base: Int) -> (Int) -> String {
// 내부 함수
func inner(inc: Int) -> String {
return "\(inc)를 반환합니다"
}
return inner
}
let fn1 = outer(base: 3) // outer()가 실행되고, 그 결과로 inner가 대입됨
let fn2 = fn1(30) // inner(inc: 30)과 동일
// 내부 함수 inner를 외부 함수의 실행 결과로 반환함으로써 외부에서 내부 함수에 접근할 수 있게됨
// inner 함수가 소멸하지 않고 fn1에 할당된 채로 생명을 유지하다가 (30)이라는 함수 호출 연산자 구문을 만나 실행됨
// 외부 함수에서 내부 함수를 반환하게 되면 외부 함수가 종료되더라도 내부 함수의 생명이 유지됨
// 내부 함수에 외부 함수의 지역 상수나 지역 변수가 참조된 경우
func basic(param: Int) -> (Int) -> Int {
let value = param + 20
func append(add: Int) -> Int {
return value + add
}
return append
}
let result = basic(param: 10) // basic 함수가 실행되고 내부 함수인 append가 반환됨
result(10) // 출력값: 40
// basic 함수는 실행이 끝나 종료, 반환된 내부 함수 append는 상수 result가 참조하고 있어 계속 남아있다가 실행됨
// 코드가 실행될 때 value 상수는 존재하지 않아 오류가 발생할 것 같지만 실행된다. 왜? append 함수가 클로저를 갖기 때문에
좋은 정보 감사합니다!