티스토리 뷰
swift는 함수도 1급 객체이기 때문에 변수 이름에 저장하거나 다른 함수의 파라미터로 전달할 수 있다. 객체지향 언어만 공부했으면 처음에는 이해하기가 힘들 수도 있지만 c++에도 최근에 추가되고 있는 함수 포인터와 같은 맥락이라고 이해하면 되겠다.
함수 타입
함수도 변수에 저장할 수 있다고 했다. 변수는 자료형을 가져야 되는데 그럼 함수를 변수에 담았을 때 그 변수는 어떤 자료형을 가질까? 함수의 원형을 생각해보면 쉽게 이해할 수 있다. 함수를 좀 더 추상적으로 생각해보자.
func add(a: Int, b: Int) -> Int {
return a + b
}
위 add함수를 보자. 함수 내용은 추상화할 수 없으니까 버리고, 파라미터와 반환값만 추상화 해보자.
- Int 자료형 변수를 2개 받아서 Int 자료형 변수 하나를 반환하는 함수
대충 이렇게 정리할 수 있다. 이게 add라는 함수의 자료형이 되고 이 자료형 변수에 저장할 수 있다.
var functionValue: (Int, Int) -> Int = add
// now functionValue is add
print(add(3, 5)) // 8
print(functionValue(3, 5)) // 8
위 두 문장은 둘 다 add라는 함수를 실행하기 때문에 같은 결과를 낸다. 기본적인 개념은 함수를 변수에 담을 수 있다는 것이고 이제 이 개념을 이용한 여러가지 응용을 알아보자.
parameter
함수를 함수의 parameter로 전달할 수 있다. 간단한 사칙연산을 출력하는 프로그램을 만들면서 공부 해보자. 먼저 기본 도구가 될 사칙연산 함수를 만든다.
func plus(a: Int, b:Int) -> Int {
return a + b
}
func minus(a: Int, b: Int) -> Int {
return a - b
}
func multiply(a: Int, b: Int) -> Int {
return a * b
}
위 함수들은 모두 같은 parameter와 return type을 가지기 때문에 같은 변수에 대입할 수 있다. 나누기는 파라미터에 따라 반환값이 Double이 될 수 있고, 그러면 자료형이 달라지므로 이 예제에서는 나누기는 생략한다.
함수와 두 Int값을 받아서 전달받은 함수에 맞는 연산을 하고 출력하게 하는 printMath함수를 구현해보자.
func printMath(f: (Int, Int)->Int, a: Int, b: Int) {
print("result = \(f(a,b))")
}
printMath(f: plus, a: 5, b: 3) // 8
printMath(f: minus, a: 5, b: 3) // 2
printMath(f: multiply, a: 5, b: 3) // 15
return type
같은 원리로 함수를 return type으로 사용할 수 있다. 이 기능을 사용해서, 전달받은 파라미터에 따라 각기 다른 함수를 돌려주는 함수 팩토리를 만들 수 있다.
func plusplus(_ input: Int) -> Int {
return input + 1
}
func minusminus(_ input: Int) -> Int {
return input - 1
}
func factory(index: Bool) -> (Int)->Int {
return index ? plusplus : minumminus
}
var gage1 = 5
var gage2 = -7
let operation1 = factory(index: gage1 < 0) // == minusminus
let operation2 = factory(index: gage2 < 0) // == plusplus
factory함수는 전달받은 파라미터의 값이 true면 plusplus함수를 반환하고 false면 minusminus함수를 반환한다. 그래서 아래의 operation들이 각 다른 함수를 뜻하게 되는 것이다.
내부 함수
함수 내부에 함수를 집어 넣을 수 있다. 이렇게 작성된 함수를 내부함수라고 하며, 기본적으로 내부 함수는 바깥에서 호출할 수 없다. 다만 반환값으로 반환될 경우 간접적으로 접근할 수 있다.
위에 있는 함수를 반환값으로 에서 작성된 예제에서 plusplus와 minusminus의 선언 및 구현부를 모두 factory 안으로 옮겨보자. 바깥에서 plusplus 또는 minusminus를 직접 호출할 경우 컴파일 에러가 발생한다. (직접 접근)
단, factory함수가 반환시켜준 goToZero를 호출하는 것은 가능하다. (간접 접근)
func factory(flag: Bool) -> (Int) -> Int {
func plusplus(_ input: Int) -> Int {
return input + 1
}
func minusminus(_ input: Int) -> Int {
return input - 1
}
return flag ? plusplus : minusminus
}
let operation = factory(flag: true)
print(plusplus(1)) // compile fail. can't direct access
print(operation(1)) // work. indirect access
'Programming > Swift' 카테고리의 다른 글
Swift Beginner | 함수의 시작과 끝 guard defer (0) | 2020.11.18 |
---|---|
Swift Beginner | Closure (0) | 2020.11.18 |
Swift Beginner | 함수(1) (0) | 2020.11.18 |
Swift Beginner | 반복문 (0) | 2020.11.18 |
Swift Beginner | 조건문 (0) | 2020.11.18 |
- Total
- Today
- Yesterday
- rxswift
- 자료구조
- winsock
- Cocos2d-x
- database
- 데이터베이스
- C++
- Spring
- swift
- 운영체제
- JSP
- SwiftUI
- C
- OS
- mongoDB
- DesignPattern
- game
- 드라마
- 국내여행
- ue4
- 수학
- SHADER
- machine learing
- SOCKET
- Git
- C/C++
- scala
- ios
- Java
- 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |