🍫 notion으로 보기
*본 포스트는 애플의 'A Swift Tour'를 바탕으로 작성되었으며, 공부하며 기록용으로 작성한 포스트이기 때문에 정확하지 않은 정보가 있을 수 있습니다!
** notion으로 작성한 문서를 임시로 올려둔 포스트이기 때문에 사진 링크의 오류와 문서의 형식 등으로 인해 보시기에 불편함이 있을 수 있습니다. (사진이 안나오거나 코드를 보기 불편한 점 등은 빠른 시일 내에 수정하도록 하겠습니다!)
**func
funcName(_ paraName: paraType) -> returnType {**
code
}
func greet(person: String, day: String) -> String {
return "Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")
자연스럽게, 함수들은 그들의 매개변수parameter 이름을 그들의 arguments의 라벨로 사용한다.
custom argument label을 매개변수parameter 이름 **앞에**
적고, argument 라벨을 사용하지 않을 경우엔 _
을 적는다.
func greet(_ person: String, on day: String) -> String {
return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")
: a custom argument label
**tuple**
을 이용해서 compound value를 만들 수 있다. ex) 함수로부터 여러 값을 반환
tuple의 요소들은 이름 혹은 숫자로부터 참조될 수 있다.
*tuple : 순서가 없는 값의 세트an ordered set of value
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0] // score 배열의 첫 번째 원소로 초기화
var max = scores[0] // score 배열의 첫 번째 원소로 초기화
var sum = 0
for score in scores { // scores 배열 안에 있는 요소 score만큼 반복
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])
//max = 100, min = 3, sum =120 => statistics = (100, 3, 120)
print(statistics.sum)
// Prints "120"
print(statistics.2) // statistics의 인덱스 (0, 1, 2)
// Prints "120"
functions can be nested. func은 함수 안에 또 다른 함수가 중첩
하여 존재할 수 있다.
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add() // y += 5, y=15
return y
}
returnFifteen()
func은 first-class 타입이다. 즉 func은 다른 func을 반환할 수 있다.
// makeIncrementer의 리턴 값: Int를 para로, Int를 반환하는 func
func makeIncrementer() -> ((Int) -> Int) {
// addOned의 리턴 값: Int
func addOne(number: Int) -> Int { // number + 1해주는 함수
return 1 + number
}
return addOne
}
var increment = makeIncrementer() // 함수 초기화
increment(7) // 실행 7+1
**func makeIncrementer()
-> ((Int) -> Int)
** // Int를 para로, Int를 반환하는 func
func addOne(number: Int)
-> **Int**
// Int를 반환하는 func
*함수의 정의 자체로 어떤 수행이 이루어지는 것은 아니다.
힘수는 매개변수로 다른 함수를 가져올 수 있다.
// condition: (Int) -> Bool : func
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
if condition(item) {
return true // *return을 만나면 함수를 빠져나간다
}
}
return false
}
// Bool을 리턴하기 때문에 ture/false 리턴
// 10보다 작으면 true, 그렇지 않으면 false
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
// numbers 정수 배열과, lessThanTen이라는 함수를 매개변수로 가져온다.
hasAnyMatches(list: numbers, condition: lessThanTen)
**func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {**
**code**
**}**
위의 함수 hasAnyMatches의 매개변수는 다음과 같다.
**list: [Int]
:** 정수Int로 이루어진 배열 list**condition: (Int) -> Bool
: Int를 입력받아 Bool 값을 리턴하는 함수 condition**그리고 for item in lis
를 통해 list의 item들은 if condition(item)
을 수행한다.
if
문의 값은 bool(true/false)이기 때문에, condition(item)
이 true일 경우에만 return true
를 만나 함수 hasAnyMatches를 빠져나가게 된다.
주어진 매개변수 var numbers = [20, 19, 7, 12]의 경우,
20, 19는 if문을 통과하지 못해 return을 만나지 못하고,
7
에서 if문을 통과해 return true
를 만나 함수 hasAnyMatches를 빠져나온다.
*7 다음 원소인 12는 수행하지 않는다.
따라서 hasAnyMatches(list: numbers, condition: lessThanTen) = true 이다.
함수는 작성된 코드 블럭이 나중에 호출될 수 있다는 점에서클로저closures의 특별한 케이스이다. (함수는 이름이 있는 클로저)클로저 안에 있는 코드는 클로저가 생성됐을 때의의 범위scope에 있는 변수나 함수와 같은 것에 접근할 수 있는데, 이는 클로저가 실행될 때 다른 범위에 있더라도 가능하다. 우리는 이미 중첩함수nested functions를 통해 그 예시를 보았다. 중괄호{}
로 코드를 묶어 이름없이 클로저를 작성할 수 있다. **in
을 사용하여 인자와 코드(로직)를 분리한다.**
numbers.map({ (number: Int) -> Int in
let result = 3 * number
return result
})
***Closure**
{ (인자들) -> 반환타입 in
code
}
***map
: 배열을 변형하는 것. 리턴 값은 같은 사이즈의, 변형된 원소들을 포함한 배열이다.**
고차함수(매개변수로 함수를 받는 함수) : map, fileer, reduce
고차함수를 사용할 수 있는 타입
**Map
: 변형. 데이터를 변형하고자 할 때 사용. 기존의 컨테이너의 값들은 변경되지 않고, 새로운 컨테이너를 생성하여 반환한다. map의 사용법은 for-in 구문과 큰 차이가 없다.** 다만, 맵을 사용하면 얻을 수 있는 이점
experiment
홀수일 경우 0을 반환하는 클로저로 수정하기
numbers.map({ (number: Int) -> Int in
let result = 3 * number
return result % 2 != 0 ? 0 : result
})
너는 클로저를 더 간결하게 작성할 수 있는 몇 가지의 옵션이 있다. 클로저의 타입이 이미 명확할 때, 예를 들어 위임에 대한 답을 할 때, 매개변수의 타입, 그것의 리턴 타입, 혹은 모두를 생략할 수 있다. single statement 클로저는 함축적으로 그들의 statement의 값을 리턴한다.
let mappedNumbers = numbers.map({number in 3 * number})
print(mappedNumbers)
위의 코드에서 number의 타입과, 리턴 타입을 생략했다.
// prints "[20, 19, 12, 7]"
// var numbers = [20, 19, 7, 12] 각 원소 *3 한 값 리턴
매개변수의 이름 대신에 숫자로 참조할 수 있다. 이 접근 특히 짧은 closures에서 유용하다. 함수를 지나가는 가는 마지막 인자일 때 클로저는 괄호 뒤에 즉각 나타날 수 있다. 클로저가 함수의 하나뿐인 인자일 때 전체 괄호**()**
는 생략해도 된다.
// Closure can omit the parentheses
let sortedNumbers = numbers.sorted { $0 > $1 }
print(sortedNumbers)
//위의 것은 이것을 줄인 것
let sortedNumbers = numbers.sort { (firstObject, secondObject) in
return firstObject > secondObject
}
***$0**
, $1
: swift에서 첫번째 객체, 두 번째 객체, ... 를 나타낼 때 줄여쓰는 표현