제어 흐름은 프로그램이 어떤 순서로 실행되는지를 결정합니다. 토파즈는 강력하고 표현력 있는 제어 흐름 구조를 제공합니다. 🎯
🔀 조건문
if 문
let 나이 = 25
let 점수 = 85
// 기본 if 문
if 나이 >= 18 {
print("성인입니다")
}
// if-else 문
if 점수 >= 90 {
print("A등급")
} else {
print("더 노력이 필요합니다")
}
// if-else if 체인
if 점수 >= 90 {
print("A등급 - 우수")
} else if 점수 >= 80 {
print("B등급 - 양호")
} else if 점수 >= 70 {
print("C등급 - 보통")
} else {
print("재시험이 필요합니다")
}
// 복합 조건
let 사용자명 = "김토파즈"
let 로그인시도 = 3
if 사용자명.length() > 0 && 로그인시도 < 5 {
print("로그인을 시도할 수 있습니다")
}
조건식
// v3에서는 ?: 대신 if 표현식을 사용하세요
let 성인여부 = if 나이 >= 18 { "성인" } else { "미성년자" }
let 통과여부 = if 점수 >= 60 { "통과" } else { "탈락" }
// 중첩 조건
let 등급 = if 점수 >= 90 { "A" }
else if 점수 >= 80 { "B" }
else if 점수 >= 70 { "C" }
else { "F" }
// 조건부 값
let 할인율 = if 회원등급 == "VIP" { 0.2 }
else if 회원등급 == "골드" { 0.1 }
else { 0.05 }
print("나이: {나이}, 상태: {성인여부}")
print("점수: {점수}, 등급: {등급}")
표현식으로서의 if
// if를 표현식으로 사용
let 메시지 = if 시간 < 12 {
"좋은 아침입니다!"
} else if 시간 < 18 {
"좋은 오후입니다!"
} else {
"좋은 저녁입니다!"
}
// 복잡한 조건부 계산
let 배송비 = if 주문금액 >= 50000 {
0
} else if 거리 <= 10 {
3000
} else {
5000
}
print(메시지)
print("배송비: {배송비}원")
🔄 반복문
for 루프
// 범위 기반 for 루프
for i in 0..5 {
print("반복 {i}")
}
// 포함 범위 (inclusive)
for i in 1..=10 {
print("숫자: {i}")
}
// 배열 반복
let 과일들 = ["사과", "바나나", "오렌지", "포도"]
for 과일 in 과일들 {
print("과일: {과일}")
}
// 인덱스와 값 함께 반복
for (인덱스, 과일) in 과일들.enumerate() {
print("{인덱스}: {과일}")
}
// 객체 키-값 반복
let 사용자정보 = {
이름: "김토파즈",
나이: 25,
직업: "개발자"
}
for (키, 값) in 사용자정보 {
print("{키}: {값}")
}
// 단계별 반복
for i in (0..20).step(2) {
print("짝수: {i}")
}
while 루프
// 기본 while 루프
let mut 카운터 = 0
while 카운터 < 5 {
print("카운터: {카운터}")
카운터 += 1
}
// 조건부 while 루프
let mut 입력 = ""
while 입력 != "종료" {
입력 = input("명령을 입력하세요 (종료하려면 '종료' 입력): ")
if 입력 != "종료" {
print("입력받은 명령: {입력}")
}
}
// 무한 루프 (break 사용)
let mut 시도횟수 = 0
while true {
시도횟수 += 1
let 성공 = Math.random() > 0.8
if 성공 {
print("성공! {시도횟수}번 시도 후 성공")
break
}
if 시도횟수 >= 10 {
print("최대 시도 횟수 초과")
break
}
}
루프 제어
// break와 continue
for i in 1..=20 {
if i % 3 == 0 && i % 5 == 0 {
print("{i}: FizzBuzz")
continue
}
if i % 3 == 0 {
print("{i}: Fizz")
continue
}
if i % 5 == 0 {
print("{i}: Buzz")
continue
}
if i > 15 {
print("15를 초과했으므로 중단")
break
}
print("{i}")
}
// 레이블이 있는 루프
외부루프: for i in 1..=3 {
for j in 1..=3 {
if i * j > 6 {
print("곱이 6을 초과하므로 외부 루프 중단")
break 외부루프
}
print("{i} × {j} = {i * j}")
}
}
🎭 패턴 매칭 (match)
기본 match 문
let 요일 = "월요일"
match 요일 {
case "월요일" => print("한 주의 시작!")
case "금요일" => print("불금!")
case "토요일" | "일요일" => print("주말!")
case _ => print("평범한 요일")
}
// 값을 반환하는 match
let 근무형태 = match 요일 {
case "월요일" | "화요일" | "수요일" | "목요일" | "금요일" => "근무일"
case "토요일" | "일요일" => "휴일"
case _ => "알 수 없음"
}
print("오늘은 {근무형태}입니다")
숫자 패턴 매칭
let 점수 = 87
let 등급 = match 점수 {
case 90..=100 => "A"
case 80..=89 => "B"
case 70..=79 => "C"
case 60..=69 => "D"
case _ => "F"
}
// 가드 조건 사용
let 평가 = match 점수 {
case x if x >= 95 => "완벽한 점수!"
case x if x >= 90 => "우수한 성과"
case x if x >= 80 => "양호한 결과"
case x if x >= 70 => "보통 수준"
case x if x >= 60 => "통과"
case _ => "재시험 필요"
}
print("점수: {점수}, 등급: {등급}, 평가: {평가}")
구조체/객체 패턴 매칭
let 사용자 = {
이름: "김토파즈",
나이: 25,
직업: "개발자",
위치: "서울"
}
// 구조 분해 매칭
match 사용자 {
case { 이름: "김토파즈", 나이, 직업: "개발자" } => {
print("토파즈 개발자님, 나이: {나이}")
}
case { 나이: age, 위치: "서울" } if age < 30 => {
print("서울의 젊은 사용자")
}
case { 직업: "개발자", 위치 } => {
print("{위치}의 개발자")
}
case _ => {
print("일반 사용자")
}
}
// 중첩된 객체 매칭
let 주문 = {
고객: { 이름: "이토파즈", VIP: true },
항목들: ["노트북", "마우스"],
총액: 1500000
}
match 주문 {
case { 고객: { VIP: true }, 총액: amount } if amount > 1000000 => {
print("VIP 고객 대형 주문: {amount}원")
}
case { 고객: { 이름 }, 항목들: items } if items.length() > 1 => {
print("{이름}님의 복수 아이템 주문")
}
case _ => {
print("일반 주문")
}
}
배열 패턴 매칭
let 숫자들 = [1, 2, 3, 4, 5]
match 숫자들 {
case [] => print("빈 배열")
case [첫번째] => print("요소 하나: {첫번째}")
case [첫번째, 두번째] => print("두 요소: {첫번째}, {두번째}")
case [첫번째, ...나머지] => {
print("첫 번째: {첫번째}, 나머지: {나머지}")
}
}
// 특정 패턴 매칭
let 점수목록 = [95, 87, 92]
match 점수목록 {
case [100, ...] => print("만점으로 시작!")
case [..., 100] => print("만점으로 끝!")
case [a, b, c] if a > 90 && b > 90 && c > 90 => print("모든 점수가 90점 이상!")
case 점수들 if 점수들.all(x => x >= 80) => print("모든 점수가 80점 이상")
case _ => print("일반적인 점수 분포")
}
열거형(enum) 패턴 매칭
enum 상태 {
대기중,
처리중(진행률: int),
완료(결과: string),
오류(메시지: string)
}
let 현재상태 = 상태.처리중(진행률: 75)
match 현재상태 {
case 상태.대기중 => print("대기 중입니다")
case 상태.처리중(진행률: progress) => {
print("처리 중: {progress}%")
if progress > 50 {
print("절반 이상 완료됨")
}
}
case 상태.완료(결과: result) => print("완료: {result}")
case 상태.오류(메시지: error) => print("오류 발생: {error}")
}
// Option 타입 매칭
let 선택값: Option<string> = Some("토파즈")
match 선택값 {
case Some(값) => print("값이 있음: {값}")
case None => print("값이 없음")
}
// Result 타입 매칭
function 나누기(a: int, b: int) -> Result<int, string> {
if b == 0 {
return Err("0으로 나눌 수 없습니다")
}
return Ok(a / b)
}
match 나누기(10, 2) {
case Ok(결과) => print("나누기 결과: {결과}")
case Err(오류) => print("오류: {오류}")
}
🛡️ 가드 조건과 고급 패턴
복합 가드 조건
let 온도 = 25
let 습도 = 60
let 계절 = "여름"
match (온도, 습도, 계절) {
case (t, h, "여름") if t > 30 && h > 70 => print("매우 덥고 습함")
case (t, h, "여름") if t > 25 && h < 50 => print("따뜻하고 건조함")
case (t, _, "겨울") if t < 0 => print("매우 추움")
case (t, h, _) if t >= 20 && t <= 25 && h >= 40 && h <= 60 => print("쾌적한 날씨")
case _ => print("보통 날씨")
}
함수형 패턴 매칭
// 재귀적 패턴 매칭으로 리스트 처리
function 리스트합계(목록: [int]) -> int {
match 목록 {
case [] => 0
case [첫번째, ...나머지] => 첫번째 + 리스트합계(나머지)
}
}
// 이진 트리 순회
enum 트리<T> {
비어있음,
노드(값: T, 왼쪽: 트리<T>, 오른쪽: 트리<T>)
}
function 트리탐색<T>(트리: 트리<T>) {
match 트리 {
case 트리.비어있음 => {
// 아무것도 하지 않음
}
case 트리.노드(값: value, 왼쪽: left, 오른쪽: right) => {
트리탐색(left)
print("노드 값: {value}")
트리탐색(right)
}
}
}
print("리스트 합계: {리스트합계([1, 2, 3, 4, 5])}") // 15
⚡ 고급 제어 흐름 패턴
루프와 패턴 매칭 결합
let 작업목록 = [
{ 타입: "이메일", 우선순위: 1, 내용: "회의 일정 확인" },
{ 타입: "전화", 우선순위: 3, 내용: "고객 상담" },
{ 타입: "문서", 우선순위: 2, 내용: "보고서 작성" }
]
for 작업 in 작업목록 {
match 작업 {
case { 타입: "이메일", 우선순위: 1, 내용 } => {
print("긴급 이메일 처리: {내용}")
}
case { 타입: type, 우선순위: priority, 내용 } if priority <= 2 => {
print("중요 {type} 작업: {내용}")
}
case { 타입, 내용 } => {
print("일반 {타입} 작업: {내용}")
}
}
}
예외 처리와 제어 흐름
// try-catch 스타일의 에러 처리
function 안전한파일읽기(파일명: string) -> Result<string, string> {
if !파일명.endsWith(".txt") {
return Err("텍스트 파일만 지원됩니다")
}
// 파일 읽기 시뮬레이션
if Math.random() > 0.7 {
return Err("파일을 찾을 수 없습니다")
}
return Ok("파일 내용입니다")
}
// 에러 처리를 포함한 제어 흐름
for 파일명 in ["data.txt", "config.json", "readme.txt"] {
match 안전한파일읽기(파일명) {
case Ok(내용) => {
print("성공적으로 읽음: {파일명}")
print("내용: {내용}")
// 성공 시 다음 파일 처리 계속
}
case Err(오류메시지) => {
print("오류 ({파일명}): {오류메시지}")
if 오류메시지.contains("지원되지") {
print("지원되지 않는 파일 형식, 건너뜀")
continue // 다음 파일로 계속
} else {
print("심각한 오류, 처리 중단")
break // 전체 처리 중단
}
}
}
}
조건부 실행 체인
// 조건부 체이닝
function 사용자처리(사용자id: int) -> Result<string, string> {
let 사용자데이터 = match 데이터베이스에서사용자가져오기(사용자id) {
case Ok(데이터) => 데이터
case Err(오류) => return Err("사용자 조회 실패: {오류}")
}
let 검증결과 = match 사용자검증(사용자데이터) {
case Ok(_) => ()
case Err(오류) => return Err("검증 실패: {오류}")
}
let 처리결과 = match 사용자데이터처리(사용자데이터) {
case Ok(결과) => 결과
case Err(오류) => return Err("처리 실패: {오류}")
}
return Ok("처리 완료: {처리결과}")
}
// 모나딕 체이닝 스타일
function 모나딕처리(사용자id: int) -> Result<string, string> {
return 데이터베이스에서사용자가져오기(사용자id)
.andThen(사용자검증)
.andThen(사용자데이터처리)
.map(결과 => "처리 완료: {결과}")
}
🎯 최적화와 베스트 프랙티스
1. 조건문 최적화
// 나쁜 예: 중복된 조건
let 점수 = 85
if 점수 >= 90 {
print("A등급")
} else {
if 점수 >= 80 {
print("B등급")
} else {
if 점수 >= 70 {
print("C등급")
} else {
print("F등급")
}
}
}
// 좋은 예: match 사용
let 등급 = match 점수 {
case 90..=100 => "A"
case 80..=89 => "B"
case 70..=79 => "C"
case _ => "F"
}
print("{등급}등급")
2. 조기 반환 패턴
function 사용자등록(이름: string, 이메일: string, 나이: int) -> Result<string, string> {
// 조기 검증 및 반환
if 이름.length() == 0 {
return Err("이름이 필요합니다")
}
if !이메일.contains("@") {
return Err("유효한 이메일이 필요합니다")
}
if 나이 < 0 || 나이 > 120 {
return Err("유효한 나이가 필요합니다")
}
// 모든 검증이 통과된 경우에만 처리
let 사용자 = 새사용자생성(이름, 이메일, 나이)
return Ok("사용자 등록 완료: {사용자.id}")
}
3. 패턴 매칭 활용
// 복잡한 비즈니스 로직을 패턴으로 표현
enum 주문상태 {
생성됨,
결제완료,
배송중,
배송완료,
취소됨
}
function 주문처리(상태: 주문상태, 결제금액: int, VIP여부: bool) -> string {
match (상태, 결제금액, VIP여부) {
case (주문상태.생성됨, _, _) => "결제를 진행해주세요"
case (주문상태.결제완료, amount, true) if amount > 100000 => {
"VIP 고객 특급 배송 준비"
}
case (주문상태.결제완료, amount, _) if amount > 50000 => {
"일반 배송 준비"
}
case (주문상태.결제완료, _, _) => "표준 배송 준비"
case (주문상태.배송중, _, true) => "VIP 배송 추적 서비스"
case (주문상태.배송중, _, _) => "배송 중"
case (주문상태.배송완료, _, _) => "배송 완료"
case (주문상태.취소됨, _, _) => "주문 취소됨"
}
}
토파즈의 제어 흐름은 강력하고 표현력이 뛰어납니다. 조건문, 반복문, 패턴 매칭을 적절히 조합하여 읽기 쉽고 유지보수하기 쉬운 코드를 작성하세요! 🚀