🔥 함수와 클로저
Swift에서는 func
키워드를 사용하여 함수를 선언할 수 있어요. 함수를 호출할 때는 함수 이름 뒤, 괄호 안에 인자 목록을 적으면 됩니다. 매개변수 이름과 타입을 함수의 반환 타입과 구분하기 위해 ->
기호를 사용하죠.
func greet(person: String, day: String) -> String { return "Hello \(person), today is \(day)." } greet(person: "Bob", day: "Tuesday")
swift
기본적으로 함수는 매개변수 이름을 인자의 레이블로 사용합니다. 매개변수 이름 앞에 사용자 정의 인자 레이블을 작성하거나 _
를 사용하여 인자 레이블을 생략할 수 있어요.
func greet(_ person: String, on day: String) -> String { return "Hello \(person), today is \(day)." } greet("John", on: "Wednesday")
swift
튜플을 사용하여 복합 값을 만들 수 있습니다. 예를 들어, 함수에서 여러 값을 반환할 때 튜플을 활용할 수 있죠. 튜플의 요소는 이름이나 번호로 참조할 수 있어요.
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) { var min = scores[0] // 최소값을 배열의 첫 번째 요소로 초기화합니다. var max = scores[0] // 최대값을 배열의 첫 번째 요소로 초기화합니다. var sum = 0 // 합계를 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) // "120"을 출력합니다. print(statistics.2) // "120"을 출력합니다.
swift
함수는 중첩될 수 있어요. 중첩된 함수는 외부 함수에서 선언된 변수에 접근할 수 있습니다. 중첩 함수를 사용하여 길거나 복잡한 함수의 코드를 구성할 수 있죠.
func returnFifteen() -> Int { var y = 10 func add() { y += 5 // 외부 함수의 변수 y에 접근하여 값을 증가시킵니다. } add() // 중첩 함수 add()를 호출합니다. return y } returnFifteen() // 15를 반환합니다.
swift
함수는 일급 타입입니다. 이는 함수가 다른 함수를 값으로 반환할 수 있다는 것을 의미해요.
func makeIncrementer() -> ((Int) -> Int) { func addOne(number: Int) -> Int { return 1 + number } return addOne } var increment = makeIncrementer() increment(7) // 8을 반환합니다.
swift
함수는 인자로 다른 함수를 받을 수 있어요.
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) // true를 반환합니다.
swift
함수는 사실 클로저의 특별한 경우입니다. 클로저는 나중에 호출할 수 있는 코드 블록이에요. 클로저의 코드는 클로저가 생성된 범위에서 사용할 수 있는 변수와 함수에 접근할 수 있습니다. 클로저가 실행될 때 다른 범위에 있더라도 말이죠. 이는 중첩 함수에서 이미 확인했던 내용이에요. 중괄호({}
)로 코드를 감싸서 이름 없는 클로저를 작성할 수 있습니다. in
키워드를 사용하여 인자와 반환 타입을 본문과 구분하죠.
numbers.map({ (number: Int) -> Int in let result = 3 * number return result })
swift
클로저를 더 간결하게 작성하는 몇 가지 옵션이 있어요. 클로저의 타입이 이미 알려진 경우, 예를 들어 대리자의 콜백인 경우, 매개변수의 타입이나 반환 타입 또는 둘 다를 생략할 수 있습니다. 단일 문장 클로저는 암시적으로 유일한 문장의 값을 반환하죠.
let mappedNumbers = numbers.map({ number in 3 * number }) print(mappedNumbers) // "[60, 57, 21, 36]"을 출력합니다.
swift
매개변수 이름 대신 번호로 매개변수를 참조할 수 있어요. 이 접근 방식은 특히 매우 짧은 클로저에서 유용합니다. 함수의 마지막 인자로 전달된 클로저는 괄호 바로 뒤에 나타날 수 있죠. 클로저가 함수의 유일한 인자인 경우, 괄호를 완전히 생략할 수 있어요.
let sortedNumbers = numbers.sorted { $0 > $1 } print(sortedNumbers) // "[20, 19, 12, 7]"을 출력합니다.
swift
클로저는 Swift에서 강력하고 유연한 기능이에요. 클로저를 사용하면 코드를 더 간결하고 표현력 있게 작성할 수 있습니다. 클로저는 함수형 프로그래밍 패러다임을 지원하며, 고차 함수와 함께 사용될 때 매우 강력해지죠.
다음은 클로저의 실제 사용 예시입니다.
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] func backward(_ s1: String, _ s2: String) -> Bool { return s1 > s2 } var reversedNames = names.sorted(by: backward) // reversedNames는 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]입니다.
swift
위 코드에서 backward(_:_:)
함수는 sorted(by:)
메서드의 by
매개변수에 전달되었어요. 이를 통해 문자열 배열을 역순으로 정렬할 수 있죠.
클로저 표현식 구문을 사용하면 이를 더 간결하게 작성할 수 있습니다.
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 })
swift
클로저의 타입이 이미 알려져 있기 때문에 매개변수 타입과 반환 타입을 생략할 수 있어요.
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
swift
단일 표현식 클로저에서는 return
키워드도 생략할 수 있죠.
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
swift
연산자 메서드를 사용하면 더 짧게 표현할 수 있어요.
reversedNames = names.sorted(by: >)
swift
이렇게 클로저는 코드를 간결하고 표현력 있게 작성할 수 있게 해줍니다. 클로저는 Swift의 강력한 기능 중 하나이며, 함수형 프로그래밍 패러다임을 지원하죠. 클로저를 잘 활용하면 더 간결하고 가독성 높은 코드를 작성할 수 있습니다.