Sign In

Swift에서의 함수

작성자
  • 한결

선언과 호출

// 선언부
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"]