티스토리 뷰

반응형
SMALL

이번 포스트에서는 Swift에서 제공하는 다양한 제어문에 대해 살펴보도록 하겠습니다.

Swift에서는 while, if, guard, switch, for-in 등 다양한 제어문을 제공합니다.

 

1. White

Swift에서는 while문과 repeat-while문 두 가지 종류의 while 문을 제공하고 있습니다.

while 조건 {
    코드 구문
}

실제 사용 예시는 아래와 같습니다.

var score = 0

while true {
	score += 10
    if score > 100 {
    	print("while문을 종료합니다.")
        break
    }
}

 

Repeat-While

Repeat - While 문은 다른 언어에서는 do-while이라고 불리는 것과 동일합니다.

repeat {
    실행 구문
} while 조건

사용 예시는 아래와 같습니다.

var value = 0
repeat {
	value += 1
} while value < 7

 

조건문

Swift 에서는 if문과 switch문의 2가지 조건문을 제공합니다.

 

if - else if - else

temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
    print("Very Cold")
} else if temperatureInFahrenheit >= 86 {
    print("Very Warm")
} else {
    print("So So")
}

 

switch

switch문의 기본 형태는 다음과 같습니다.

switch some value to consider {
case value 1:
    // respond to value 1
case value 2,
     value 3:
    // respond to value 2 or 3
default:
    otherwise, do something else
}

각 case 별로 실행 구문이 1줄도 없을 경우에는 break문을 반드시 넣어주어야 합니다. 그렇지 않을 경우 컴파일 오류가 발생합니다.

 

암시적인 진행을 사용하지 않음 (No Implicit Fallthrough)

C와 Objective-C의 switch문과는 달리 Swift의 switch문은 암시적인 진행(Implicit Fallthrough)을 하지 않습니다.

C나 Objective-C에서는 switch 구문이 기본적으로 모든 case를 순회하여 default를 만날 때까지 진행됩니다. 그래서 그것을 방지하기 위해 break라는 문구를 명시적으로 적어야 했습니다. Swift에서는 break를 적지 않아도 case안의 실행 구문이 모두 실행되면 자동으로 switch문을 빠져 나오게 됩니다. 이로 인해 실수로 break를 적지 않아도 의도하지 않은 case문이 실행되는 상황을 피할 수 있습니다.

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a": // Invalid, case문에 body가 없으므로 에러 발생
case "A":
    print("The letter A")
default:
    print("Not the letter A")
}

case 안에 콤마(,)로 구분해서 복수 case 조건을 혼합하여 사용이 가능합니다.

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
    print("The letter A")
default:
    print("Not the letter A")
}

만약에 다음 case로 이동하고 싶다면 fallthrough를 사용하면 됩니다.

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
    print("The letter A")
    fallthrough
case "b", "B":
	print("The letter B")
default:
    print("Not the letter A")
}

숫자의 특정 범위 조건 사용이 가능합니다.

let approximateCount = 62
let countedThings = "moons orbiting Saturn"
let naturalCount: String
switch approximateCount {
case 0:
    naturalCount = "no"
case 1..<5:
    naturalCount = "a few"
case 5..<12:
    naturalCount = "several"
case 12..<100:
    naturalCount = "dozens of"
case 100..<1000:
    naturalCount = "hundreds of"
default:
    naturalCount = "many"
}
print("There are \(naturalCount) \(countedThings).")

숫자의 범위를 case의 조건으로 지정할 수도 있습니다.

 

Value Binding ( 값 바인딩 )

변수를 사용하여 값을 바인딩하는 조건을 걸 수도 있습니다. 예를 들어 Tuple (x, y)가 있을 때 앞의 값은 중요하지 않고 뒷 값이 0인 경우를 찾고자 한다면 다음과 같이 사용할 수 있습니다.

let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
    print("뒷 값이 0 앞 값은 무관")
case (0, let y):
    print("앞 값이 0 뒷 값은 무관")
case let (x, y):
    print("둘 다 무관")
}

 

Where 사용 가능

case 조건문에 where를 사용할 수 있습니다.

let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
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")
}

 

For-In 문

For-In Statements는 배열, 숫자, 문자열을 순서대로 순회(iteration)하기 위해 사용합니다.

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
    print("Hello, \(name)!")
}

사전(dictionary)에서 반환된 키(key)-값(value) 쌍으로 구성된 튜플을 순회하며 제어할 수도 있습니다.

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs")
}

사전(dictionary)에 담긴 콘텐츠는 정렬이 되지 않은 상태이기 때문에 사전에 넣었던 순서대로 Iteration되지 않는 다는 점을 알아두시면 좋을 것 같습니다.

 

조건 부분에 숫자 범위를 지정하여 iteration할 수 있습니다.

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}

 

만약 순서대로 Iteration을 할 필요가 없다면, 변수자리에 _키워드를 사용하면 성능을 높일 수 있습니다.

let base = 3
let power = 10
var answer = 1
for _ in 1...power {
    answer *= base
}
print("\(base) to the power of \(power) is \(answer)")

 

Control Transfer Statements

제어 전송 구문은 코드의 진행을 계속 할지, 그만 할지를 결정하거나, 실행되는 코드의 흐름을 변경하기 위해 사용합니다.

Swift에서는 5가지의 제어 전송 구문(Control Transfer Statements)을 제공합니다.

continue
break
return
throw
fallthrough

 

continue문은 현재 Iteration 중인 Loop를 중단하고 다른 Iteration Loop을 실행하도록 합니다.

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
    if charactersToRemove.contains(character) {
        continue
    } else {
        puzzleOutput.append(character)
    }
}
print(puzzleOutput)

break문은 전체 제어문의 실행을 중지시킵니다. break문은 loopswitch문에서 사용할 수 있습니다.

해당 Loop를 빠져 나갈 수 있습니다.

let numberSymbol: Character = "三"  // 중국어로 3을 의미하는 문자입니다.
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "١", "一", "๑":
    possibleIntegerValue = 1
case "2", "٢", "二", "๒":
    possibleIntegerValue = 2
case "3", "٣", "三", "๓":
    possibleIntegerValue = 3
case "4", "٤", "四", "๔":
    possibleIntegerValue = 4
default:
    break
}
if let integerValue = possibleIntegerValue {
    print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
    print("An integer value could not be found for \(numberSymbol).")
}

fallthrough 키워드는 이후의 case에 대해서도 실행하게 합니다. 앞에서 언급했던 것 처럼 Swift에서는 한번 특정 case를 타면 바로 그 switch 문은 종료됩니다. 마치 case 안에 break를 자동으로 넣은 것과 같은 기능을 하는 것이죠. 하지만 이 fallthrough 를 사용하면 이 자동으로 break가 사용되는 것을 막는 효과를 가져옵니다.

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
print(description)
주의할 점 : fallthrough 는 case 조건을 확인하지 않고 그냥 다음 case를 실행하게 만듭니다.

레이블 구문 (Labeled Statements)

아래와 같은 형태로 label 이름과 while 조건을 넣어 특정 구문을 실행하는 구문으로 사용할 수 있습니다.

label name: while condition {
    statements
}

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!")

Early Exit (이른 탈출)

guard문을 이용해 특정 조건을 만족하지 않으면 이 후 코드를 실행하지 않도록 방어코드를 작성할 수 있습니다.

func greet(person: [String: String]) {
    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).")
}

greet(person: ["name": "John"])
// Prints "Hello John!"
// Prints "I hope the weather is nice near you."
greet(person: ["name": "Jane", "location": "Cupertino"])
// Prints "Hello Jane!"
// Prints "I hope the weather is nice in Cupertino."

이용가능한 API 버전 확인 (Checking API Availability)

Swift에서는 기본으로 특정 플랫폼 (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
}


// 예시

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
}

 

이번 포스트에서는 Swift의 제어문에 대해 살펴보았습니다.

반응형
LIST

'프로그래밍언어 > Swift' 카테고리의 다른 글

Swift 함수  (0) 2020.02.23
Swift 메모리 안정성  (0) 2020.02.16
Swift Collection Types (컬렉션 타입)  (0) 2020.02.10
Swift 문자열과 문자  (0) 2020.02.09
Swift의 기본 연산자  (0) 2020.02.09
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함