Swift 공부 2

Paul Mo·2023년 10월 22일
0

Functions and Closures

함수를 선언하려면 'func'를 사용하고, 함수를 호출하려면 함수 이름 다음에 괄호 안에 인수를 넣어 호출한다. '->'를 사용하여 함수의 매개변수 이름 및 유형을 함수의 반환 유형과 구분한다. 자바스크립트에서는 function을 다 쓰거나 arrow function으로 '() => {}' 이렇게 사용하고는 하는데 이런 차이점이 있다.

func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")

기본적으로 함수는 매개변수 이름을 인수의 레이블로 사용하는데, 사용자가 정의한 인수 레이블을 매개변수 이름 앞에 작성하거나 이것을 사용하지 않으려면 '_'를 사용하면 된다.

func greet(_ person: String, on day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")

Tuple을 사용하면 함수에서 여러 값을 반환할 수 있다. Tuple의 요소는 이름 또는 번호로 참조할 수 있다.

func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0


    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }


    return (min, max, sum)
}
let statistics = calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
// Prints "120"
print(statistics.2)
// Prints "120"

함수는 일급 객체 타입이기 때문에 함수가 다른 함수를 반환할 수 있다.

1급 객체란?
아래 3 가지조건을 충족한다면 1급 객체라고 할수 있습니다.
1. 변수나 데이타에 할당 할 수 있어야 한다.
2. 객체의 인자로 넘길 수 있어야 한다.
3. 객체의 리턴값으로 리턴 할수 있어야 한다.

func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)

함수는 클로저(closures)의 특수한 케이스라고 한다. 클로저는 나중에 호출할 수 있는 코드 블록이다. 자바스크립트의 callback 함수가 생각났는데, 같은 의미의 개념으로 이해하면 될 것 같다. 클로저 내의 코드는 클로저가 생성된 범위에서 사용 가능한 변수 및 함수와 같은 요소에 액세스 할 수 있고, 클로저가 실행될 때 다른 범위에 있더라도 해당 범위에서 사용 가능하다. 중괄호({})로 코드를 둘러싸면 이름 없는 클로저를 작성할 수 있는데 자바스크립트의 익명함수처럼 사용 가능하다. 그리고 매개변수와 반환 유형을 몸체에서 분리하기 위해 'in'을 사용한다.

numbers.map({ (number: Int) -> Int in
    let result = 3 * number
    return result
})

클로저를 더 간결하게 작성하는 여러 가지 방법이 있다. 클로저의 유형이 이미 알려진 경우(delegate의 콜백과 같은 경우), 매개변수의 유형, 반환 유형 또는 둘 다를 생략할 수 있는 방법도 있다. 단일 문 클로저는 암시적으로 그 유일한 문의 값을 반환한다.

let mappedNumbers = numbers.map({ number in 3 * number })
print(mappedNumbers)
// Prints "[60, 57, 21, 36]"

매개변수를 이름 대신 번호로 참조할 수도 있으며, 이 방법은 매우 짧은 클로저에서 특히 유용하게 사용된다. 클로저가 함수의 마지막 인수로 전달되면 괄호 바로 뒤에 나타날 수 있다. 클로저가 함수의 유일한 인수인 경우 괄호를 완전히 생략할 수도 있다.

let sortedNumbers = numbers.sorted { $0 > $1 }
print(sortedNumbers)
// Prints "[20, 19, 12, 7]"

참조:

profile
프론트 엔드 개발자

0개의 댓글

관련 채용 정보