[Swift🦩] #5 μ œμ–΄ 흐름, #6 ν•¨μˆ˜

λ˜μƒΒ·2022λ…„ 3μ›” 21일
0

iOS

λͺ©λ‘ 보기
18/42
post-thumbnail

5. μ œμ–΄ 흐름

for, while, if, guard, switch, break, continue

λ‹€λ₯Έ 언어와 거의 λ™μΌν•˜λ‹€κ³  봐도 λ¬΄λ°©ν•˜λ‹€.

1. For-In 루프

λ°°μ—΄, 숫자 λ²”μœ„, λ¬Έμžμ—΄, λ”•μ…”λ„ˆλ¦¬, ... 에 for - in 루프λ₯Ό μ μš©ν•΄μ„œ μš”μ†Œ ν•˜λ‚˜ν•˜λ‚˜μ— μ ‘κ·Όν•  수 μžˆλ‹€.

μ•ž λ‚΄μš©μ—μ„œ λŒ€μ²΄λ‘œ λ‹€λ€˜μ—ˆκ³ , μ΅μˆ™ν•˜κΈ° λ•Œλ¬Έμ— λ‚΄κ°€ λ„ˆλ¬΄λ‚˜λ„ 잘 μžŠμ–΄λ²„λ¦¬λŠ”

for (index, value) in enumarated(arr) {
}

for i in stride(from: 0, to: 10, by: 2) { 
    // 10 은 포함 μ•ˆλ¨.
}

for i in stride(from: 0, through: 10, by: 2) { 
    // 10 포함.
}

만 μ“°κ³  λ„˜μ–΄κ°€λ„λ‘ ν•˜κ² λ‹€. νŒŒμ΄μ¬μ—μ„œλŠ” enumerate(arr) / range(0, 10, 2) 이라 항상 ν—·κ°ˆλ¦Ό


2. while / repeat ~ while

λ‹€λ₯Έ μ–Έμ–΄μ˜ while, do ~ while κ³Ό κ°™λ‹€. 쑰건이 true 인 λ™μ•ˆ 반볡 / μ²«λ²ˆμ§ΈλŠ” 쑰건 따지지 μ•Šκ³  μ‹€ν–‰ ν›„ 반볡.


3. 쑰건문

1. if ~ else if ~ else


2. switch ⭐️

Swift switch 의 νŠΉμ§•

  • swift λŠ” break λ₯Ό 적지 μ•Šμ•„λ„ λœλ‹€.
    λ‹€λ₯Έ μ–Έμ–΄μ—μ„œλŠ” μΌ€μ΄μŠ€λ§ˆλ‹€ break λ₯Ό 걸어주지 μ•ŠμœΌλ©΄ λ‹€μŒκ²ƒκΉŒμ§€ λͺ¨λ‘ μ‹€ν–‰λ˜μ§€λ§Œ, Swift λŠ” μ•„λ‹˜. 였히렀, μ›λž˜μ²˜λŸΌ μ•„λž˜ μΌ€μ΄μŠ€κΉŒμ§€ μ‹€ν–‰λ˜κ²Œ ν•˜κ³  μ‹ΆμœΌλ©΄, fallthrough λ₯Ό λͺ…μ‹œμ μœΌλ‘œ 써쀀닀. ⭐️
  • switch 문에 μ •μˆ˜λ‚˜ 문자만이 μ•„λ‹ˆλΌ, νŠœν”Œ, enum 같은 것듀을 넣을 수 μžˆλ‹€.
switch int(score / 10) {
case 10, 9: print("A") // , 둜 λ‚˜λˆ„κΈ°λ„ κ°€λŠ₯.
case 8: print("B")
case 7: print("C")
case 6: print("D")
default: print("F")
}

// 숫자 λ²”μœ„λ‘œ μ“°λŠ” 것도 κ°€λŠ₯ν•˜λ‹€.
switch score {
case 90...100: print("A")
case 80..<90: print("B")
case 70..<80: print("C")
case 60..<70: print("D")
default: print("F")
}

3. switch - tuple / where ⭐️

case λ₯Ό λ¬΄μ‹œν•˜λ €λ©΄ _ 둜 λ„£μ–΄μ£Όλ©΄ λœλ‹€.

let somePoint = (1, 1)
switch somePoint {
case (0, 0):
    print("\(somePoint) is at the origin")
case (_, 0):
    print("\(somePoint) is on the x-axis")
case (0, _):
    print("\(somePoint) \(y) is on the y-axis")
case (-2...2, -2...2):
    print("\(somePoint) is inside the box")
default:
    print("\(somePoint) is outside of the box")
}
// Prints "(1, 1) is inside the box"

값을 λ°”μΈλ”©ν•΄μ„œ μ‚¬μš©ν•  μˆ˜λ„ 있고, where μ ˆμ„ μ΄μš©ν•΄μ„œ λ°”μΈλ”©ν•œ κ°’μ˜ 쑰건을 λ”°μ§ˆ μˆ˜λ„ μžˆλ‹€.

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) where x == y:
    print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    print("(\(x), \(y)) is just some arbitrary point")
}
// Prints "on the x-axis with an x value of 2"

4. μ œμ–΄ λ³€κ²½ ꡬ문

continue, break, fallthrough, return(ν•¨μˆ˜), throw(μ—λŸ¬ 핸듀링)

1. continue

ν˜„μž¬ λ°˜λ³΅ν•˜κ³  μžˆλŠ” 단계λ₯Ό κ±΄λ„ˆλ›°κ³ , λ‹€μŒ λ°˜λ³΅μ„ μ‹œμž‘.

2. break ⭐️

ν˜„μž¬ λ°˜λ³΅λ¬Έμ„ λΉ μ Έλ‚˜κ°.
or switch λ¬Έμ—μ„œ break μ•žμ— μžˆλŠ” 쑰건을 μ œμ™Έν•œ 것을 λ¬΄μ‹œ. default: break

3. fallthrough

switch 문이 C 처럼 λ™μž‘ν•  수 있게, λ‹€μŒ λ‹¨κ³„λ‘œ 흐λ₯΄κ²Œ λ§Œλ“€μ–΄μ€€λ‹€.

+) 라벨을 μ΄μš©ν•΄μ„œ νŠΉμ • λ°˜λ³΅λ¬Έμ„ λΉ μ Έλ‚˜κ°ˆ 순 μžˆμ§€λ§Œ, 잘 μ•ˆ μ“°μž„.

gameLoop: while square != finalSquare {
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    switch square + diceRoll {
    case finalSquare:
        // diceRoll will move us to the final square, so the game is over
        break gameLoop
    case let newSquare where newSquare > finalSquare:
        // diceRoll will move us beyond the final square, so roll again
        continue gameLoop
    default:
        // this is a valid move, so find out its effect
        square += diceRoll
        square += board[square]
    }
}
print("Game over!")

5. Early Exit (guard) ⭐️

ν•¨μˆ˜λ‚˜ ν΄λ‘œμ € λ‚΄μ—μ„œ, μ–΄λ–€ 쑰건을 λ§Œμ‘±ν•΄μ•Όν•˜λŠ” λ³€μˆ˜μ— 따라 λ‹€μŒ λ¬Έμž₯의 싀행을 κ²°μ •ν•œλ‹€.
πŸ“• ν•΄λ‹Ή λ³€μˆ˜λ₯Ό ν• λ‹Ήν•˜λŠ” λ¬Έμž₯을 κ²€μ‚¬ν•΄μ„œ true 이면 λ‹€μŒ λ¬Έμž₯을 μ‹€ν–‰ν•˜κ³ , κ·Έ 쑰건이 거짓이 되면 μƒμœ„ 블둝을 νƒˆμΆœν•˜λŠ” λ¬Έμž₯을 else 문에 μž‘μ„±ν•œλ‹€.
πŸ“• 보톡은 else λ¬Έμ—μ„œ return 이 μ‚¬μš©λ˜μ§€λ§Œ, 상황에 따라 break continue throw λͺ¨λ‘ μ‚¬μš© κ°€λŠ₯. νƒˆμΆœμ΄λ‹ˆκΉŒ~
πŸ“• μ˜ˆμ™Έ μƒν™©λ§Œμ„ μ²˜λ¦¬ν•˜κ³  싢을 λ•Œ if λŒ€μ‹  guard λ₯Ό μ‚¬μš©ν•œλ‹€.

func greet(person: [String: String]) {
    // λ”•μ…”λ„ˆλ¦¬μ— name 이 μ—†μœΌλ©΄ κ·Έλƒ₯ 끝남.
    guard let name = person["name"] else { return }

    print("Hello \(name)!")

    // λ”•μ…”λ„ˆλ¦¬μ— μœ„μΉ˜ 정보가 μ—†μœΌλ©΄ 이름, μ•ˆλ‚΄λ¬Έκ΅¬λ§Œ 뽑고 끝남.
    // μ˜΅μ…”λ„ 바인딩도 κ°€λŠ₯.
    guard let location = person["location"] else {
        print("I hope the weather is nice near you.")
        return
    }

    print("I hope the weather is nice in \(location).")
}
// OS λ²„μ Όμ—μ„œ κ°€λŠ₯ν•œ API 인지 μ²΄ν¬ν•΄μ„œ μ‚¬μš©ν•˜λŠ”λ° μ‚¬μš©ν•œλ‹€.
// guard λ¬ΈμœΌλ‘œλ„ μ‚¬μš© κ°€λŠ₯
if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}



6. ν•¨μˆ˜

νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” μ½”λ“œ λΈ”λŸ­.
보톡 같은 κΈ°λŠ₯을 ν•˜λ©΄μ„œ λ‘λ²ˆ 이상 λ°˜λ³΅λ˜λŠ” 것을 λ¬Άμ–΄μ„œ ν•¨μˆ˜λ‘œ λ§Œλ“ λ‹€.

ν•¨μˆ˜ 이름, 인자, λ°˜ν™˜ νƒ€μž…, λ°˜ν™˜κ°’μ΄ μžˆλŠ” ν˜•νƒœλ‘œ λ‹€λ₯Έ μ–Έμ–΄μ˜ ν•¨μˆ˜μ™€ κ΅¬μ‘°λŠ” λ™μΌν•˜κΈ° λ•Œλ¬Έμ—, Swift ν•¨μˆ˜μ˜ νŠΉμ΄ν•œ 점만 μ •λ¦¬ν•˜κ² λ‹€.

1. 인자 이름에 라벨을 μ€€λ‹€ ⭐️

func greet(person name: String) -> String {
    return "Hello, " + name + "!";
}

ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ νŒŒλΌλ―Έν„°λ₯Ό λ„˜κ²¨μ€„ λ•Œ μ‚¬μš©ν•˜λŠ” 이름과 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ ν•΄λ‹Ή 인자λ₯Ό μ‚¬μš©ν•˜λŠ” 이름이 λ‹€λ₯΄λ‹€.
ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ νŒŒλΌλ―Έν„° 이름 라벨을 μƒλž΅ν•˜κ³  μ‹ΆμœΌλ©΄ _ λ₯Ό μ‚¬μš©ν•œλ‹€.

πŸ“• μ›λž˜ μ•ˆλ˜λŠ” ν‚€μ›Œλ“œλ„ `parametername` 처럼 ` λ₯Ό λΆ™μ—¬μ„œ μ£Όλ©΄ λŒ€λΆ€λΆ„μ˜ 이름을 νŒŒλΌλ―Έν„° μ΄λ¦„μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

2. tuple? 을 λ°˜ν™˜ν•  수 μžˆλ‹€.

사싀 이건 λ‹€λ₯Έ μ–Έμ–΄μ—μ„œλ„ κ°€λŠ₯ν•˜μ§€λ§Œ, tuple 에 라벨을 쀄 수 μžˆλ‹€λŠ” 것은 νŠΉμ΄ν•˜λ‹€.
그리고 νŠœν”Œμ— λŒ€ν•œ μ˜΅μ…”λ„μ„ λ°˜ν™˜ν•  수 μžˆλ‹€λŠ”κ±΄ νŠΉμ΄ν•˜λ‹€.

func minMax(array: [Int]) -> (min: Int, max: Int) {
    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)
}

let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)") 
// λ°˜ν™˜ν•˜λŠ” νŠœν”Œμ˜ 값을 라벨 μ΄λ¦„μœΌλ‘œ μ‚¬μš©.
// Prints "min is -6 and max is 109"

3. ν•¨μˆ˜ λ°”λ””κ°€ ν•œμ€„μ΄λ©΄, μ•”μ‹œμ  return 이 λœλ‹€.

4. 기본값을 쀄 수 μžˆλ‹€.

func addTwo(first: Int, second: Int = 2) {
    return first + second
}

addTwo(first: 1) // 3
addTwo(first: 10, second: 3) // 13

πŸ“• κΈ°λ³Έ 값이 μ—†λŠ” λ§€κ°œλ³€μˆ˜λ₯Ό κΈ°λ³Έ 값이 μžˆλŠ” 것보닀 μ•žμ— λ°°μΉ˜ν•˜λŠ” 것이 μ’‹κ³ ,
κΈ°λ³Έ κ°’ 여뢀와 상관없이 더 μ€‘μš”ν•œ 값을 μ•žμ— λ°°μΉ˜ν•˜λŠ” 것이 μ’‹λ‹€.

5. κ°€λ³€ νŒŒλΌλ―Έν„°

같은 νƒ€μž…μ˜ νŒŒλΌλ―Έν„°κ°€ μ—¬λŸ¬κ°œ λ“€μ–΄μ˜¬ 수 μžˆμ„ λ•Œ,
인자 νƒ€μž…μ„ Type... 으둜 지정해주면, ν•΄λ‹Ή νƒ€μž…μ˜ 0개 μ΄μƒμ˜ μΈμžκ°€ λ“€μ–΄μ˜¬ 수 μžˆλ‹€.

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)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers

6. inout νŒŒλΌλ―Έν„°

ν•¨μˆ˜ μ•ˆμ—μ„œ 볡사값이 λ°”λ€Œλ‹ˆκΉŒ, C 의 포인터λ₯Ό μ΄μš©ν•΄ μ£Όμ†Œκ°’μ„ λ„˜κ²¨μ„œ λ°”κΎΈλŠ” κ²ƒμ²˜λŸΌ
inout ν‚€μ›Œλ“œλ₯Ό λ„£μ–΄μ„œ, ν•¨μˆ˜ λ°–μ˜ 값이 λ°”λ€”μˆ˜ 있게 ν•΄μ€€λ‹€.

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var num1 = 0
var num2 = 1
swapTwoInts(&num1, &num2)

πŸ“• ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ—μ„œλŠ” μ§€μ–‘ν•˜λŠ” 것이 μ’‹λ‹€.

  1. ν•¨μˆ˜κ°€ 호좜 될 λ•Œ μ „λ‹¬μΈμžμ˜ 값을 λ³΅μ‚¬ν•˜κ³ 
  2. λ³΅μ‚¬ν•œ 것을 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 값을 λ³€κ²½
  3. ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λ©΄μ„œ λ³€κ²½λœ 값을 μ›λž˜ λ§€κ°œλ³€μˆ˜μ— ν• λ‹Ή

-> Memory Safety λ₯Ό 보μž₯ν•˜μ§€ μ•Šμ„ 수 있음.

πŸ“• inout 은 κΈ°λ³Έκ°’ X, κ°€λ³€ νŒŒλΌλ―Έν„° X


7. ν•¨μˆ˜ νƒ€μž…

ν•¨μˆ˜λ₯Ό type 으둜 μ‚¬μš©ν•  수 μžˆλ‹€.

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}

// λ³€μˆ˜μ— ν•¨μˆ˜λ₯Ό ν• λ‹Ή κ°€λŠ₯.
var mathFunction: (Int, Int) -> Int = addTwoInts

인자둜 ν•¨μˆ˜λ₯Ό λ„˜κ²¨μ€„ 수 있음.

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// Prints "Result: 8"

ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•  μˆ˜λ„ 있음.

func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}

8. 쀑첩 ν•¨μˆ˜

ν•¨μˆ˜ μ•ˆμ— ν•¨μˆ˜λ₯Ό μ •μ˜ν•  수 μžˆλ‹€. 그러면 κ·Έ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” λ²”μœ„λŠ” μ»€λ‹€λž€ ν•¨μˆ˜ μ•ˆ!

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
}

πŸ“• 9. μ’…λ£Œλ˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ Never

  • μ •μƒμ μœΌλ‘œ λλ‚˜μ§€ μ•ŠλŠ” ν•¨μˆ˜. == λΉ„λ°˜ν™˜ ν•¨μˆ˜
  • 였λ₯˜λ₯Ό λ˜μ§„λ‹€λ˜κ°€, 였λ₯˜λ₯Ό λ³΄κ³ ν•˜κ³  ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œν•΄λ²„λ¦¬κΈ° λ•Œλ¬Έ.
  • guard 문의 else λΈ”λ‘μ—μ„œλ„ 호좜 κ°€λŠ₯
  • λŒ€ν‘œμ μΈ μ˜ˆμ‹œκ°€ fatalError
func crashAndBurn() -> Never {
    fatalError("fatal error")
}

πŸ“• 10. λ°˜ν™˜ 값을 λ¬΄μ‹œν•  수 μžˆλŠ” ν•¨μˆ˜

  • ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 경우, 컴파일러 κ²½κ³ λ₯Ό μ—†μ• μ£ΌλŠ” μ½”λ“œ @discardableResult
@discardableResult func discardableResultSay(_ something: String) -> String {
    print(something)
    return something
}

discardableResultSay("hi") // λ°˜ν™˜κ°’μ„ μ‚¬μš©ν•˜μ§€ μ•Šμ§€λ§Œ 컴파일러 κ²½κ³  μ•ˆλœΈ.
profile
0λ…„μ°¨ iOS κ°œλ°œμžμž…λ‹ˆλ‹€.

0개의 λŒ“κΈ€