switch 문을 사용한 제어 흐름
다른 프로그래밍 언어처럼 Go도 switch
문을 지원합니다. switch
문은 여러 if
문이 연결되지 않게 하기 위한 목적으로 사용합니다. switch
문을 사용하면 많은 if
문을 포함하는 코드를 유지하고 읽어야 하는 어려움을 방지할 수 있습니다. 이러한 문을 사용하면 복잡한 조건도 쉽게 만들 수 있습니다. 다음 섹션에서 switch
문을 살펴보겠습니다.
기본 switch 구문
if
문과 마찬가지로 switch
조건에는 괄호가 필요하지 않습니다. 가장 단순한 형태의 switch
문은 다음과 같습니다.
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
sec := time.Now().Unix()
rand.Seed(sec)
i := rand.Int31n(10)
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
}
fmt.Println("ok")
}
위의 코드를 여러 번 실행할 경우 매번 다른 출력이 표시됩니다. (그러나 Go Playground에서 코드를 실행하면 매번 동일한 결과를 얻게 됩니다. 그것이 서비스의 제한 사항 중 하나입니다.)
Go는 조건과 일치하는 항목을 찾을 때까지 switch
문의 사례를 각각 비교합니다. 그러나 이전 코드가 num
변수 값으로 가능한 모든 경우를 포함하지는 않습니다. num
이 5
이면 프로그램 출력은 ok
입니다.
기본 사용 사례에 대해 다음과 같이 좀 더 구체적으로 포함시킬 수도 있습니다.
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
default:
fmt.Print("no match...")
}
default
case는 유효성을 검사하는 식을 작성하지 않습니다. i
변수의 값은 case
문에 대해 유효성을 검사하고 default
사례는 유효성이 검사되지 않은 값을 처리합니다.
여러 식 사용
둘 이상의 식이 단 한 개의 case
문과 일치하는 경우가 간혹 있습니다. Go에서 case
문에 둘 이상의 식을 포함하려면 쉼표(,
)를 사용하여 식을 구분합니다. 이 방법을 사용하면 중복된 코드를 방지할 수 있습니다.
다음 코드 샘플에서는 여러 식을 포함하는 방법을 보여줍니다.
package main
import "fmt"
func location(city string) (string, string) {
var region string
var continent string
switch city {
case "Delhi", "Hyderabad", "Mumbai", "Chennai", "Kochi":
region, continent = "India", "Asia"
case "Lafayette", "Louisville", "Boulder":
region, continent = "Colorado", "USA"
case "Irvine", "Los Angeles", "San Diego":
region, continent = "California", "USA"
default:
region, continent = "Unknown", "Unknown"
}
return region, continent
}
func main() {
region, continent := location("Irvine")
fmt.Printf("John works in %s, %s\n", region, continent)
}
case
문의 식에 포함하는 값은 switch
문이 유효성을 검사하는 변수의 데이터 형식에 해당합니다. 새 case
문으로 정수 값을 포함하는 경우 프로그램에서 컴파일하지 않습니다.
함수 호출
switch
에서 함수를 호출할 수도 있습니다. 이 함수에서 가능한 반환 값에 대한 case
문을 작성할 수 있습니다. 예를 들어 다음 코드는 time.Now()
함수를 호출합니다. 출력은 현재 요일에 따라 달라집니다.
package main
import (
"fmt"
"time"
)
func main() {
switch time.Now().Weekday().String() {
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
fmt.Println("It's time to learn some Go.")
default:
fmt.Println("It's the weekend, time to rest!")
}
fmt.Println(time.Now().Weekday().String())
}
switch
문에서 함수를 호출할 경우 함수가 반환하는 항목의 유효성을 항상 검사하기 때문에 식을 변경하지 않고 해당 논리를 수정할 수 있습니다.
또한 case
문에서도 함수를 호출할 수 있습니다. 예를 들어 정규식을 사용하여 특정 패턴을 일치시키려면 이 기법을 사용합니다. 예를 들면 다음과 같습니다.
package main
import "fmt"
import "regexp"
func main() {
var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`)
var phone = regexp.MustCompile(`^[(]?[0-9][0-9][0-9][). \-]*[0-9][0-9][0-9][.\-]?[0-9][0-9][0-9][0-9]`)
contact := "foo@bar.com"
switch {
case email.MatchString(contact):
fmt.Println(contact, "is an email")
case phone.MatchString(contact):
fmt.Println(contact, "is a phone number")
default:
fmt.Println(contact, "is not recognized")
}
}
switch
블록에는 유효성 검사 식이 없습니다. 이 개념은 다음 섹션에서 살펴봅니다.
조건 생략
Go에서 if
문에서 하는 방식으로 switch
문에서 조건을 생략할 수 있습니다. 이 패턴은 switch
문을 항상 강제로 실행하는 것처럼 true
값을 비교하는 것과 같습니다.
조건 없이 switch
문을 작성하는 방법의 예는 다음과 같습니다.
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
r := rand.Float64()
switch {
case r > 0.1:
fmt.Println("Common case, 90% of the time")
default:
fmt.Println("10% of the time")
}
}
조건이 항상 true이기 때문에 프로그램은 항상 이 유형의 switch
문을 실행합니다. 조건부 switch
블록은 if
및 else if
문의 긴 체인보다 유지 관리가 더 쉬울 수 있습니다.
논리가 다음 case로 넘어가게 하기
일부 프로그래밍 언어에서는 모든 case
문의 끝에 break
키워드를 작성합니다. 그러나 Go에서는 논리가 하나의 case에 빠질 경우 명시적으로 중지하지 않으면 switch
블록을 종료합니다. 논리를 바로 다음 case로 넘어가게 하려면 fallthrough
키워드를 사용합니다.
이 패턴을 이해하려면 다음 코드 샘플을 살펴봐야 합니다.
package main
import (
"fmt"
)
func main() {
switch num := 15; {
case num < 50:
fmt.Printf("%d is less than 50\n", num)
fallthrough
case num > 100:
fmt.Printf("%d is greater than 100\n", num)
fallthrough
case num < 200:
fmt.Printf("%d is less than 200", num)
}
}
코드를 실행하고 출력을 분석합니다.
15 is less than 50
15 is greater than 100
15 is less than 200
무언가 잘못된 것이 보이나요?
num
이 15(50 미만)이기 때문에 첫 번째 case와 일치합니다. 그러나 num
은 100 이하입니다. 그리고 첫 번째 case
문에는 fallthrough
키워드가 있기 때문에 이 논리는 case의 유효성을 검사하지 않고 바로 다음 case
문으로 이동합니다. 따라서 fallthrough
키워드를 사용할 때는 주의해야 합니다. 이 코드가 만드는 동작이 필요하지 않을 수 있습니다.