티스토리 뷰

Programming/Swift

Swift Beginner | 함수(2)

글그리 2020. 11. 18. 18:43

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
링크
«   2024/05   »
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 29 30 31
글 보관함