-For-In문(For-In Loops) : 배열, 숫자, 문자열을 순서대로 순회(iterate)하기 위해 사용.
ex)```
let names = ["Anna", "Alex", "Brian", "Jack" ]
for name in names {
print("Hello, \ (name)!")
}
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!
-사전에서 반환된 키key-값value 쌍으로 구성된 튜플을 순회하며 제어할 수도 O
ex) ```
let dict = ["A":1, "B":2, "C":3]
for (character, count) in dict {
print("\ (character) with \ (count)")
}
//사전에 담긴 콘텐츠는 정렬이 되지 않은 상태
-> 값을 넣은 순서대로 순회되지 Xx,,
-숫자 범위 지정도 O
ex) for ~~ in 1...5 {
..}
-순서대로 제어할 필요가 없다면 변수자리에 _키워드를 사용하면 성능을 높일 수 O
ex)```
let base = 3
let power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
printf("\ (base) to the power of \ (power) is \ (answer)")
// 3 to the power of 10 is 59049
-범위 연산자와 함께 사용 O
ex)```
let minutes = 60
for tickMark in 0..<minutes {
//render the tick mark each minute (60 times)
}
- **stride(from:to:by:)** 함수와 함께 사용할 수 O
ex) 구간을 5로 설정한 경우
```
let minuteInterval = 5
for tickMark in stride(from:0, to: minutes, by: minuteInterval){
//render the tick mark every 5 minutes (0, 5, 10, ... , 50, 55)
}
-While문 (While Loops): while, repeat-while 두 가지 종류
-While : 조건(condition)이 거짓(false)일 때까지 구문(statements)을 반복
while condition {
statements
}
-Repeat-While문 : (다른 언어의 do-while문과 유사)
구문statements을 최소 한 번 이상 실행하고 while 조건이 거짓일 때까지 반복
repeat {
statements
} while condition
-조건적 구문(Conditional Statements): if와 switch문 두 가지
-If문
-Switch문
>기본 형태```
switch some value to consider {
case value 1:
respond to value 1
case value 2,
value 3: //복수의 case조건 혼합(compound) 가능
respond to value 2 or 3
default:
otherwise, do something else
}
-암시적인 진행을 사용하지 Xx,,(No Implicit Fallthrough) -> break 적지 않아도 특정 case가 완료되면 자동으로 switch 구문을 빠져나오게 됨
(break가 Swift에서 필수적이지는 않지만 case안의 특정 지점에서 멈추도록 하기 위해 break 사용 가능!)
-case 안에 최소 하나의 실행 구문이 반드시 있어야 함!
-> case문에 body가 없으면 error!
-fallthrough 키워드: 하나의 case문을 거친 뒤, 그 다음 case 문의 내용을 이어서 실행하도록 동작
switch문 내부의 어떤 곳에서든 사용 O
(마지막 case문 제외)
-> continue, break, return, throw 등과 같은 제어 전송문(Control Transfer Statements)
-인터벌 매칭(Interval Matching): 숫자의 특정 범위를 조건으로 사용할 수 O
```
switch approximateCount {
case 0:
naturalCount = "no"
case 1..<5:
naturalCount = "a few"
case 5..<12:
...
-튜플(Tuple): 튜플을 조건으로 사용할 수 O
튜플(Tuple)이란 유한 개의 사물의 순서있는 열거.
() 안에 다양한 데이터 값을 넣어주면 된다
-값 바인딩(Value Bindings): 특정 x, y 값을 각각 다른 case에 정의하고 그 정의된 상수를 또 다른 case에서 사용하는 것
ex) ```
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
print("on the x-axis with an x value of (x)")
case (0, let y):
print("on the y-axis with a y value of (y)")
case let (x, y):
print("somewhere else at ((x), (y))")
}
// on the x-axis with an x value of 2
-Where 문
ex) switch yetAnotherPoint {
case let (x, y) where x == y:
print("((x), (y)) is on the line x == y")
-혼합 케이스(Compound Cases): case에 콤마(,)로 구분해 여러 조건을 혼합해 사용 O, 혼합 케이스에서도 값-바인딩 사용 O
-제어 전송 구문(Control Transfer Statements): 코드의 진행 여부 결졍 or 실행되는 코드의 흐름을 바꾸기 위해 사용, 다섯 가지(continue, break, fallthrough, return, throw) 제공
>continue문: 현재 loop 중지, 다음 loop를 수행하도록 함.
>break문: 전체 제어문의 실행을 즉각 중지시킴, loop나 switch문에서 사용할 수 있음.
>fallthrough문: 이후의 case에 대해서도 실행하게 함
(case 조건을 확인하지 Xx,, 그냥 다음 case를 실행하게 만듬!)
-레이블 구문(Labeled Statements): label 이름과 while 조건을 넣어 특정 구문을 실행하는 구문
label name: while condition
{
statements
}
ex) ```
label_1 : for i in 1...9
{
label_2 : for j in 1...9
if j==5
{
break label_1
}
}
}
-이른 탈출(Early Exit): guard 문을 이용해 특정 조건을 만족하지 않으면 이후 코드를 실행하지 않도록 방어코드 작성.
-guard문 : guard "조건" else {조건이 false일 때 실행될 구문}
>반드시 return이나 throw로 구문을 종료시킬 수 있도록 해야 함.
>```
func solution() {
guard condition1 else { return print("Bye!")}
guard condition2 else { return print("Bye!")}
print("Come In")
}
-이용가능한 API 버전 확인(Chedking API Availability) : 특정 플랫폼(iOS, macOS, tvOS, watchOS)과 특정 버전을 확인하는 구문 제공
>기본 형태
```
if #available(platform name version, ..., *) {
statements to execute if the APIs are available
} else {
fallback statements to execute if the APIs are unavailable
}
-정의와 호출(Defining and Calling Functions):
>함수 선언할 때 : 가장 앞에 func 키워드,
(person: Strin) 파라미터와 형, ->String 형태로 반환형 정의
ex)```
func greet(person: String) -> String {
let greeting = "Hello, " + person + "!"
return greeting
}
//메시지 결합부분과 반환부분 합치면
func greetAgain(person: String) -> String {
return "Hello again, " + person + "!"
//호출
print(greet(person: "Anna"))
// Hello, Anna!
-파라미터가 없는 함수 (Functions Without Parameters)
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld())
//hello, world
-복수의 파라미터를 사용하는 함수 (Functions With Multiple Parameters)
func greet(person: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return greetAgain(person: person)
} else {
return greet(person: person}
}
}
print(greet(person: "Tim", already Greeted: true))
//Hello again, Tim!
-반환값이 없는 함수 (Functions Without Return Values)
>반환 값이 정의되지 않은 함수는 Void라는 특별한 형 반환
-복수의 값을 반환하는 함수 (Functions with Multiple Return Values) : 튜플을 함수의 반환 값으로 사용할 수 O
-옵셔널 튜플 반환형(Optional Tuple Return Types) : 반환 값에 ?물음표가 붙음. (min: Int, max: Int)?
> 값이 있을 수도 있고 없을 수도 있는 변수 -> 옵셔널Optional, 타입에 ?을 붙여야 함 > 옵셔널에 초기값을 지정하지 않으면 기본값은 nil(비어 있다)let optionalEmail: String? = "sjy3729@naver.com" let requiredEmail: String = optionalEmail //Compile Error>requiredEmail 변수는 옵셔널 Xx,, String이기 때문에 항상 값을 가지고 있어야 함! 반면에 optionalEmail은 옵셔널로 선언된 변수 -> 실제 코드가 실행되기 전까지는 값이 있는지 없는지 알 수 Xx -> requiredEmail에 옵셔널로 선언된 변수 대입 불가!
ex)```
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
>실제 반환 값에 접근하기 위해서 if let과 같은 옵셔널 체인 사용 or 강제 unwrapping(? 사용) 을 해야함
>옵셔널 바인딩Optional Binding : 옵셔널의 값이 존재하는지를 검사한 뒤, 존재한다면 그 값을 다른 변수에 대입시켜줌, if let 또는 if var 사용 옵셔널의 값을 벗겨서 값이 O -> if문 안으로 들어가고, 값이 nil -> 그냥 통과 ``` if let email = optionalEmail { print(email) // optionalEmail의 값이 존재한다면 해당 값이 출력됩니다. } // optionalEmail의 값이 존재하지 않는다면 if문을 그냥 지나칩니다.>콤마(,)로 구분하여 여러 옵셔널을 바인딩 할 수 O, 이때 사용된 모든 옵셔널의 값이 존재해야 if문 안으로 진입.
>옵셔널 체이닝Optional Chaining ``` struct Person { var name : String var contacts : Contacts init(name : String, email : String, address : String) { self.name = name contacts = Contacts(email: email, address: ["home" : address]) } } var my : Person? = Person(name: "Song", email: "sjy3729@naver.com", address: "pangyo") //my라는 변수가 nil인지의부를 확인, //->만약 nil이 아닐 경우 본래의 값 반환, nil이면 그냥 nil 반환. print(my?.contacts.email) // Optional("sjy3729@naver.com") my = nil print(my?.contacts.email) // nil
-인자 라벨 지정(Specifying Argument Labels): 파라미터 앞에 인자 라벨 지정 -> 실제 함수 내부에서의 인자 이름과 함수 호출시 사용하는 이름을 다르게 할 수 있음
ex)```
func greet(person: String, from hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
// Hello Bill! Glad you could visit from Cupertino.
-파라미터 앞에 _을 붙여 함수 호출 시 인자값을 생략할 수 O
ex) ```
func hello(_ first: Int, second: Int) {
}
hello(1, second: 2)
-기본 파라미터 값(Default Parameter Values): 함수의 파라미터 값에 기본 값(: Int = 12)을 설정할 수 O, 기본 값이 설정되어 있는 파라미터는 함수 호출 시 생략 가능!!
-집합 파라미터(Variadic Parameters): 인자 값으로 특정 type의 집합 값을 사용할 수 O
ex) ```
func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
//return 3.0
-인-아웃 파라미터(In-Out Parameters): 인자 값을 직접 변경하는 파라미터.
>파라미터 앞에 inout 키워드를 사용하여 선언
ex) ```
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"
>>위의 예시에서 함수의 인자에 변수를 넣을 때 & 키워드 사용 (inout 파라미터는 포인터를 넣는다고 생각하기!)
- 인-아웃 파라미터는 기본 값을 가질 수 Xx,,
- 집합 파라미터는 inout으로 선언될 수 Xx,,
-함수 형 (Function Types): 파라미터 형(parameter types), 반환 형(return type)
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
var mathFunction: (Int, Int) -> Int = addTwoInts
//함수를 변수로 정의해서 사용
//변수 mathFunction은 addTwoInts 함수의 인자 값과 반환 값이 같으므로 이 함수가 변수로 할당될 수 O
print("Result: \(mathFunction(2, 3))")
// Result: 5
let anotherMathFunction = addTwoInts
//변수나 상수에 함수를 할당할 때 직접 함수 형을 선언하지 않아도 Swift가 형을 추론해(Type Inferred) 자동으로 함수를 할당할 수 O
// anotherMathFunction is inferred to be of type (Int, Int) -> Int
>파라미터에 함수 형 사용 O
>함수를 반환하는 함수 만들 수 O
-중첩 함수(Nested Functions) : 다른 함수 안의 body에서 동작하는 함수
>함수 밖에서는 감춰져 있고 함수의 body 내에서 접근 가능
ex)```
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero는 이제 중첩 돼 있는 stepForward() 함수를 가르킵니다.
while currentValue != 0 {
print("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!