드디어, 함수 마지막 파트까지 도달했네요!
앞서 다룬 함수관련 포스팅의 내용 중...
- 함수의 표기법 (Function Notation) : 함수를 '명명'하는 일종의 규칙
- 함수의 타입(Function Type) : 함수 또한 일종의 '복합타입'
위 2가지 매우 간단한 개념은
이번 포스팅에서 배울 1급 객체함수에서 활용됩니다.
Swift의 프로그래밍 패러다임과 1급 객체
Swift는, 함수형 프로그래밍 지향 패러다임에 따라 1급 객체로서의 조건을 갖춘다
'1급 객체' 란 생소한 개념은,
Swift란 프로그래밍 언어의 패러다임에서 시작됩니다.
현재 다루고 있는 Swift란 언어는
'객체지향 언어'이자, '함수형 프로그래밍' 패러다임을 지향하는 언어입니다.
(CS 파트에서 객체지향 및 함수형 프로그래밍에 대해 보다 구체적으로 다루도록 하겠습니다)
함수의 특징과 1급객체의 조건
- Swift의 언어 패러다임에 따라, 함수는 하나의 객체(Object)입니다.
- 각각의 함수(객체)는 서로 주고-받으며 자료를 처리할 수 있습니다.
- 그렇기 때문에, 함수는 '1급 시민(First-Citizen)'의 조건을 충족합니다.
- 함수가 1급 시민, 즉 1급 객체가 되기 위해선 3가지 조건이 있습니다.
- 변수 또는 상수에 함수를 할당할 수 있어야 한다. (Binding)
- 함수의 반환값(Return)으로 함수(객체)를 사용할 수 있어야 한다.
- 함수의 매개변수(Parameters)로 함수(객체)를 전달할 수 있어야 한다. (Callback)
Swift의 함수는,
위 3가지 조건을 모두 만족합니다.
1급 객체함수의 3가지 조건
값으로서 ①저장되고, ②반환값과 ③파라미터로 활용!
Swift에서의 함수가,
어떻게 '1급 객체'로서 활용 가능하고, 작성될 수 있는지..
1급 객체가 되기 위한 3가지 조건에 따른 예시를 통해 구체적으로 살펴보도록 하겠습니다.
첫 번째, 변수 또는 상수에 할당할 수 있어야 한다 (Binding)
- 함수 자체를 변수 또는 상수에 대입(할당)하게 되면?
- 해당 변수와 상수는 함수 그 자체로서 활용되게 됩니다!
- 함수의 이름 ➟ 변수와 상수에 대입(할당) ➟ 함수의 기능 부여
// 파라미터로 추가되는 값에서 1씩 빼는 함수를 만들고,
func countDidMinus(count: Int) -> Int {
return count - 1
}
// minus란 상수에 함수 countDidMinus를 할당함!
let minus = countDidMinus
// 해당 상수를 호출하고, 처리값으로 4을 대입하면?
// 정상적으로 함수의 기능이 작동한다!
minus(4) // 3
- 만약, 같은 이름의 함수(Overloading)를 변수 또는 상수에 대입(할당)하게 된다면..
- 반드시, 해당 변수와 상수의 타입을 명시(Type Annotations)해야 합니다!
- 여기서 타입은, 앞선 포스팅에서 학습한 '함수 타입' 입니다.
// 아래와 같이 동일한 이름의 함수(오버로딩)가 있을 경우
func coundDidPlus(_ count: Int) { }
func coundDidPlus(_ count: Int, _ label: String) { }
let plus = coundDidPlus // 컴파일러 Error 발생!
// 따라서, 함수의 타입을 작성해줌으로서 구분해야 함
// 첫 번째 함수를 할당하고자 한다면?
let plus1: (Int)-> () = coundDidPlus
// 정상적으로 할당
- 또한, 같은 이름과 같은 파라미터/리턴타입을 가지고 있는 함수가 있을 경우..
- 여기선, 대입(할당)하는 함수에 표기법(Function Notation)을 명명 해야합니다.
- XCode에서 코드를 작성할 시, 자동으로 표기법을 완성시켜줍니다.
// 아래와 같이 동일한 이름의 함수(오버로딩)가 있고,
// 타입(파라미터 형태) 또한 동일하다면?
func countWillDivide(count: Int) { }
func countWillDivide(_ count: Int) { }
// 이와 같이, 함수의 표기법을 이용하여 대입(할당)한다.
// 첫 번째 함수를 할당하고자 한다면?
let divide1 = countWillDivide(count:)
// 정상적으로 할당
두 번째, 함수의 반환값(Return Value)으로 함수를 사용할 수 있어야 한다.
- 함수의 반환값 (Return [ ... ])으로서 함수를 사용한다?
- 말 그대로, 함수 그 자체의 기능을 반환할 수 있습니다.
- 예시 코드를 먼저 살펴보자면, 다음과 같습니다.
func outside () -> () -> () {
func inside() {
print("inside 함수가 반환되었습니다.")
}
return inside
}
let callInside = outside()
callInside() // "inside 함수가 반환되었습니다"
- 함수를 반환하려면, 해당 함수의 반환 타입에 '함수타입'을 작성해야 합니다.
- 위 코드를 보면, 'outside'란 함수 내 'inside'란 함수를 반환값으로 활용합니다.
- 그런데, outside 함수의 매개변수와 리턴타입의 모양이 ( ) -> ( ) -> ( ) ???
func outside (①parameters) -> (②parameters) -> (②return type)
|
① outside 함수
② outside 함수의 리턴타입 (즉, inside 함수의 타입)
세 번째, 함수의 매개변수(Parameters)로 함수를 사용할 수 있어야 한다.
- 함수의 반환값으로 매개변수를 사용할 수 있었으니, 매개변수로도 가능하겠죠?
- 이는 흔히 콜백(Callback) 함수라고 하며, 주로 클로저를 통해 작성합니다.
(클로저는 다음 포스팅에서 구체적으로 다룰 예정입니다.) - 예시 코드를 살펴보자면, 다음과 같습니다.
- 이는 흔히 콜백(Callback) 함수라고 하며, 주로 클로저를 통해 작성합니다.
// 매개변수로 활용할 함수 messageA를 선언함
func messageA() {
print("Hello, Lime")
}
// 콜백함수를 작성하고, 매개변수 타입을 함수타입으로 작성함
func messageB(_ callback: () -> ()) {
callback() // 매개변수를 반환함!
// ()을 붙여주는 이유는, 함수를 '실행'해야 하기 때문
}
messageB(messageA) // "Hello, Lime"
드디어 기본적인 함수 포스팅이 마무리 되었습니다 !
함수의 타입과 표기법은 활용 및 명명 방식이 다소 헷갈릴 수 있으므로
반드시 1급 객체함수와 함께 복습하시길 바랍니다.
다음 포스팅에서는,
함수와 동일한 개념이지만, '이름이 없는 함수'
클로저(Closure)에 대해 살펴보겠습니다.
'iOS > Swift' 카테고리의 다른 글
[iOS/Swift] 클로저 표현식(Closure Expression)과 1급 객체 조건 (0) | 2023.01.26 |
---|---|
[iOS/Swift] 익명 혹은 람다함수는 모두 클로저(Closure)일까? (0) | 2023.01.25 |
[iOS/Swift] 함수의 타입(Type)과 형태를 알아보자! (0) | 2023.01.10 |
[iOS/Swift] 함수를 부르는 방식, 함수 표기법(Function Notation) (0) | 2023.01.09 |
[iOS/Swift] 매개변수는 사실 상수였다?! (함수를 호출하는 2가지 방법) (0) | 2022.11.17 |
댓글