Design/Swift

[Swift] Chapter01.Tour - 2

공밀레의 재료 2025. 4. 22. 22:48
반응형

Functions and Closures

함수를 선언하기 위해서 func 을 사용한다. func의 뒤에 적히는 함수의 호출명과 괄호안에는 전달인자(argument)를 통해서 함수를 호출한다. 함수의 반환 유형에서 매개변수의 이름과 유형을 구분하려면 -> 을 사용한다.

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

 

기본적으로 function은 매개변수의 이름을 전달인자의 label로 사용한다. 하지만 매개변수 앞에 사용자 지정 전달인자의 label을 작성하거나, _를 사용해서 사용자 지정 label을 사용하지 않을 수 있다.

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

 

함수에서 여러 값을 반환하는 등의 동작을 하려면 튜플(tuple)을 사용한다. 튜플의 요소는 이름이나 번호로 참조 할 수 있다.

Tuple
여러 개의 값을 하나의 복합으로 묶을 수 있는 type. 각각의 값은 서로 다른 type일 수도 있고, 이름을 붙일 수도 있다.

let person = ("Tommy", 30)
print(person.0) // "Tommy"
print(person.1) // 30

let person = (name: "Tommy", age: 30)
print(person.name) // "Tommy"
print(person.age) // 30
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"

 

함수는 중칩될 수 있고, 중첩된 함수는 외부 함수에서 선언된 변수에 access 할 수 있다. 중첩된 함수를 사용하면 길거나 복잡한 코드를 간결하게 줄일 수 있다.

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

 

함수는 first-class type이다. 즉, 함수의 반환(return) 할때 다른 함수를 반환할 수 있다.

func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

 

함수는 다른 함수를 arguments로 받을 수 있다.

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)

 

함수는 closer의 형태중 하나다. 클로저는 나중에 실행 할 수 있는 코드 블록을 의미하는데, 클로저 내부의 코드는 클로저가 만들어졌던 범위 안의 변수나 함수에 접근이 가능하다. 클로저를 사용할때는 이름 없이 중괄호 {}로 코드를 감싸면 클로저를 만들 수 있다. in 키워드를 사용해서 매개변수와 반환 타입을 본문과 구분 할 수 있다.

numbers.map({ (number: Int) -> Int in
    let result = 3 * number
    return result
})
func makeIncrementer(by amount: Int) -> () -> Int {
    var total = 0
    let incrementer: () -> Int = {
        total += amount
        return total
    }
    return incrementer
}

let incrementByTwo = makeIncrementer(by: 2)
print(incrementByTwo()) // 2
print(incrementByTwo()) // 4
let greeting = {
    print("Hello!")
}
greeting() // 실행

 

클로저를 간결하게 작성하기 위한 옵션이있다. 클로저의 유형을 다 알고있는 경우 매개변수의 유형, 반환 유형 또는 둘 다를 생략 할 수 있다. 단일 statement의 클로저는 암시적으로 단일 statement 값을 반환한다.

아래의 예시에서 number in 3 * number 는, number in return 3 * number를 생략한 것이다.
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]
반응형