Swift에서의 함수

Created by
  • 한결

선언과 호출

// 선언부 func someFunction(_ wildCard: Type, argumentlabel parameter: Type, ..) { ... logic(parameter) ... } // 호출부 someFunction(wildCardValue, argumentlabel: argumentValue)
파라미터 이름을 지정한다는 점과 와일드카드를 이용하여 인자 이름을 조절할 수 있다는 점이 특징이다.
반환 타입 명시는 func name () → returnType { } 형식으로 지정한다.
함수 내부에 다른 로직 없이 바로 return 문이 올 경우, return 키워드를 달지 않아도 된다.
다른 프로그래밍 언어와 선언, 호출, 활용 방식이 거의 동일하다.

함수는 일급 객체다.

💡
일급?
- 함수 자체를 변수/상수에 담을 수 있다. (함수의 반환 값을 담는걸 의미하지 않는다.)
- 반환값에 함수를 담을 수 있다. (= 함수 반환값에 객체를 전달할 수 있다.)
- 매개변수에 함수를 담을 수 있다.
1.
변수, 상수에 함수 그 자체를 담을 수 있다.
func sayHelloFn(name: String) { print("\(name), 안녕~!") } func sayHelloFn(name: String) -> String { return "\(name), 안녕~!" } let fn: (String) -> Void = sayHelloFn(name:) let fn2: (String) -> String = sayHelloFn(name:) fn("한결") fn2("한결")
이것의 의미는 변수/상수의 타입을 함수로 한다는 의미다. (인자) → 반환값
someButton.addTarget(self, action: #selector(fn), for: .touchUpInside) // someButton이 터치될 경우에만 // selector 함수에 인자로 넘겨준 '함수 타입'의 함수를 실행시킨다. // 함수 자체를 호출하지 않고, 함수 자체를 넘겨준다. @objc func fn() {}
함수의 호출 형식을 확장시켜 사용할 수 있다.
변수/상수에 함수를 담을 때, 동일한 이름의 함수를 담을 경우 타입에 대한 명확한 명시가 필요하다.
(이건 Swift 언어의 함수 오버로딩 지원으로 반드시 필요한 부분이다.)
2.
반환값에 함수(객체)를 담을 수 있다.
enum CalcType { case plus, minus } func plus(_ first: Int, _ second: Int) -> Int { return first + second } func minus(_ first: Int, _ second: Int) -> Int { return first - second } func basicCalc(calcType: CalcType) -> (Int, Int) -> Int { return calcType == .plus ? plus : minus } let result = basicCalc(calcType: .plus) let result2 = basicCalc(calcType: .minus) result(5, 3) // 8 result2(5, 3) // 2
최종적인 반환 타입은 가장 마지막 → 의 오른쪽에 지정해준다.
함수 내부에서는 반환하는 구문에서 실행을 처리할 함수 자체를 담아줄 수 있다.
3.
함수 매개변수로 함수를 담을 수 있다.
enum BrokerType { case incr, decr } func incrOrDecr(_ num: Int, _ type: BrokerType) -> Int { return type == .incr ? num + 1 : num - 1 } func broker(_ baseNum: Int, brokerType: BrokerType, cb: (Int, BrokerType) -> Int) -> Int { return cb(baseNum, brokerType) } let result3 = broker(1, brokerType: .incr, cb: incrOrDecr(_:_:) // 2 let result4 = broker(1, brokerType: .decr, cb: { v, t in return t == .decr ? v - 1 : v + 1 }) // 0
함수의 인자로 콜백 함수를 담을 수 있다.
이 콜백 함수는, 조건에 따라서 함수 내부에서 반환 구문에서 특정 인자들을 담아서 실행시키는 용도로 인자에 들어온다.
인자에 반영해야 하는 콜백 함수를 익명 함수로 호출부에 정의해줄 수 있다. result4와 같은 경우

클로저

배열의 고차함수

JavaScript와 비슷하게 forEach, map, filter, reduce 등의 대표적인 배열 기반의 고차함수를 지원한다.
고차함수에 인자로 들어가는 클로저를 지정하는 방식은 JavaScript와 다르다. 각 순환 요소를 $0 형태로 내부 인자로 사용할 수 있다.
["a", "b", "c", "d"].map { $0 + "-" } // ["a-", "b-", "c-", "d-"] ["a", "b", "c", "d"].filter { $0 == "a" } // ["a"]