Swift는 객체지향 언어이자 함수형 언어이다.
함수형 언어가 되기 위해서는 일급 함수의 조건을 만족해야 한다.
Swift에서 Closure는 매우 중요한 개념인데, 이를 이해하기 위해서는 일급함수의 개념을 이해하는 것이 필수이다!
일급 객체의 조건
1. 객체가 런타임에도 생성이 가능해야 한다
2. 인자값으로 객체를 전달할 수 있어야 한다
3. 반환값으로 객체를 사용할 수 있어야 한다
4. 변수나 데이터 구조 안에 저장할 수 있어야 한다
5. 할당에 사용된 이름과 관계없이 고유한 구별이 가능해야 한다
함수가 위 조건을 만족하면 이를 일급 함수(First-Class Function)이라고 하고, 이 언어를 함수형 언어로 분리한다.
즉 함수를 객체처럼 취급하는 게 함수형 언어의 특징인 것이다!
일급 함수의 특성
첫번째 특성, 변수나 상수에 함수를 대입할 수 있다.
말그대로 함수를 변수나 상수에 할당한다는 것이다.
func show(something: String) -> String {
return "This is \(something)"
}
let fn = show
let result = fn("Macbook") // This is Macbook
fn이라는 상수에 show(something:)이란 함수를 대입했다.
따라서 fn은 show(something:)과 이름만 다르고 인자값, 기능 반환값이 같은 함수가 된다.
이때 fn은 '함수 타입'(Function Types)이다.
변수에 정수를 대입하면 Int 타입, 문자열을 대입하면 String 타입이 되는 것과 똑같은 논리이다.
fn은 함수를 대입했으므로 함수 타입이다
함수타입은 입력값, 반환값 두가지로 구성된다.
(인자 타입1, 인자 타입2, 인자 타입3, ...) -> 반환 타입
위의 show(something:) 함수의 함수 타입은 (String) -> String이다.
만약 인자값을 3개를 갖는 함수 [func boo(a: Int, b: String, c: String) -> Void]가 있다면,
해당 함수의 타입은 다음과 같다. (Int, String, String) -> String
함수도 타입이기 때문에, 변수나 상수를 함수 타입으로도 선언할 수 있다.
func show(something: String) -> String {
return "This is \(something)"
}
let fn1 = show
let fn2: (String) -> String = show(something:)
이때, fn1과 fn2는 같은 함수를 갖고 있는 함수타입의 상수이다. 다른 이름 같은 내용이다!
두번째 특성, 함수의 반환 타입으로 함수를 사용할 수 있다.
일급 객체로 대우받는 함수는 실행 결과로 기본 자료형, 클래스 구조체 뿐만 아니라 함수도 반환할 수 있다.
func printSomething(something: String) -> String {
return "print \(something)"
}
func show() -> (String) -> String {
return printSomething
}
let fn1 = show
let value1 = fn1() // value1 == printSomething()
let value2 = value1("hello") // value2 == print hello
fn1은 함수 show()를 대입받은 함수타입의 상수이다.
value1은 함수 show()의 반환값인 printSomething() 함수를 갖고 있다.
value2는 value1인 printSomething() 함수의 반환값을 출력한다.
세번째 특성, 함수의 인자값으로 함수를 사용할 수 있다
Swift는 기본 자료형(Int, String...), 구조체, 클래스 타입처럼 '함수 타입(Function Types)'을 정의할 수 있다고 했다.
따라서 함수 타입을 이용하면 함수도 다른 함수의 인자로 넘길 수 있다.
func increment(param: Int) -> Int {
return param + 1
}
func broker(base: Int, function: (Int) -> Int) -> Int{
return function(base)
}
broker(base: 2, function: increment) // 결과값: 3
broker 함수는 인자로 Int 타입의 값과 와 (Int) -> Int 타입의 함수를 받는다.
이렇게 함수를 인자로 넘기게 되면 런타임 시점에 결과를 확인할 수 있기에 컴파일 시점에 디버깅할 수 없다는 단점이 있지만, 동적으로 함수 내부의 실행을 제어할 수 있다는 장점이 있다.
즉, 함수의 내부 코드를 수정하지 않고도 외부에서 함수 내부의 실행 과정을 제어할 수 있다는 것이다.
이것이 함수를 인자로 넘기는 가장 큰 목적 중 하나이다.
함수 외부에서 함수 내부에 실행 구문을 추가할 수 있다는 것은, 함수를 그만큼 재활용 할 수 있다는 말이다.
Swift에서는 보통 함수 수행의 성공, 실패를 처리하는 함수를 인자값으로 받아 처리한다.
하지만 매번 성공, 실패 처리를 위해 함수를 따로 선언해서 넘겨주는 것은 비효율적이고 또 코드만 차지하게 된다.
이러한 일회용적 함수를 지원하기 위해 많은 함수형 언어들이 익명함수를 지원한다.
익명함수란, 함수는 함수인데 이름이 선언되지 않는 일회용 함수이다.
Swift도 익명함수를 지원하는데, 이를'Closure'라고 부른다.
'iOS > Swift' 카테고리의 다른 글
[iOS] UIImage -> CGImage 변환시 이미지 방향이 변하지 않게 하기 (0) | 2022.01.09 |
---|---|
[iOS] UIImagePickerController에서 가져온 이미지에서 GPS 정보 파싱하기 (0) | 2021.12.25 |
[iOS] 프로토콜 (Protocol ) (0) | 2021.12.19 |
[iOS] Dark mode 사용하지 않기 (Light mode 강제 설정하기 ) (0) | 2021.12.12 |
[iOS] Codable - JSON Encoding 과 Decoding 하기 (0) | 2021.12.11 |