조건 증가 for문
for var i = 0; i < 20; i += 2 { // C 스타일 for문
print(i);
}
/* 실행 결과
main.swift:1:1: error: C-style for statement has been removed in Swift 3
for var i = 0; i < 20; i += 2 {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
*/
Swift3에서 사라진 C 스타일 for문은 사용할 수 없다.
/* 사용불가
for var i = 0; i < 20; i += 2 {
print(i);
}
*/
for i in 1...5 { // ...으로 1부터 5까지
print("반복");
}
/* 실행 결과
main.swift:6:5: warning: immutable value 'i' was never used; consider replacing with '_' or removing it
for i in 1...5 {
^
_
반복
반복
반복
반복
반복
*/
... 범위 연산자를 사용하면 범위를 지정하여 반복할 수 있다. 시작과 끝을 포함하며 위의 예시에서 1...5는 1, 2, 3, 4, 5를 의미한다.
그런데 실행 결과를 보면 경고가 뜨는 것을 확인할 수 있다.

변수 i를 선언하고 카운트 변수로만 이용하고 사용하지 않았기 때문에 경고로 알려준 것이다.
for _ in 1...5 {
print("반복");
}
/* 실행 결과
반복
반복
반복
반복
반복
*/
_를 사용하면 경고를 없앨 수 있다. _는 무시한다는 의미이다. 대신 지정해 두었던 i는 당연하게도 사용하지 못한다.
for i in 1...10 {
print("안녕 \(i) 번째")
}
/* 실행 결과
안녕 1 번째
안녕 2 번째
안녕 3 번째
안녕 4 번째
안녕 5 번째
안녕 6 번째
안녕 7 번째
안녕 8 번째
안녕 9 번째
안녕 10 번째
*/
문자열 안에서 \(변수)를 사용하게 되면 변수의 값을 문자열과 합쳐진 형태로 변환이 가능하다. 자바에서 연결 연산자 +를 이용해 문자열을 합치는 것과 같은 역할을 수행한다.
그리고 이제 i를 사용하였기 때문에 경고가 더이상 뜨지 않는 것을 확인할 수 있다.
for i in 1...10
print("안녕 \(i) 번째")
/* 실행 결과
main.swift:1:16: error: expected '{' to start the body of for-each loop
for i in 1...10
*/
그리고 for in 반복문에서는 중괄호를 무조건 써주어야 한다. 자바에서는 한 문장만 반복문 블록 안에서 실행된다면 중괄호 블록을 없앨 수 있지만 스위프트는 중괄호{}를 반드시 작성해주어야한다.
let nums = [1, 2, 3, 4] // Integer를 담는 배열
for num in nums[1..<3] { // 1부터 2의 인덱스까지
print(num)
}
/* 실행 결과
2
3
*/
배열의 항목을 지정할 때에도 범위 지정 연산자를 사용할 수 있다. 대괄호[] 안에 범위 지정 연산자를 이용하여 특정 범위를 표현할 수 있다. 범위 연산자에 관한 내용은 이전 포스트를 참고하면 좋다.
https://megamaker.tistory.com/157
[Swift][3주차] 연산자와 Optional
연산자(Operator) 연산자의 우선순위와 결합 법칙 Operator Declarations | Apple Developer Documentation Operator Declarations | Apple Developer Documentation Work with prefix, postfix, and infix operators. developer.apple.com 스위프트의
megamaker.tistory.com
let nums = [1, 2, 3, 4] // Integer를 담는 배열
for num in nums[1...] { // 1부터 2의 인덱스까지
print(num)
}
/* 실행 결과
2
3
4
*/
이렇게 1부터 그 이후 모든 인덱스 지정하는 것을 사용할 수도 있다. (꼭 1이 아니어도 됨)
딕셔너리 (Dictionary)
let names = [1 : "손흥민", 2 : "이승우", 3 : "차범근"] // 딕셔너리
for (id, name) in names { // Key, Value 쌍
print(id, "이름:", name)
}
/* 실행 결과
2 이름: 이승우
3 이름: 차범근
1 이름: 손흥민
*/
딕셔너리는 키와 값으로 이루어진 자료구조이다. 자바의 Map이나 C#의 딕셔너리와 같은 역할이다. 대신 자바에서 Map을 사용할 때 각 키,값 쌍을 가져오려면 순서가 없기 때문에 Map.EntrySet<>을 사용해서 가져와야 했었는데 스위프트에서는 괄호만 사용하면 쉽게 그 키와 값 쌍을 가져올 수 있다.
while문
var count = 0;
while count < 5 {
count += 1 // count++는 안 됨...
print(count)
}
/* 실행 결과
1
2
3
4
5
*/
for문은 보통 몇 번 반복할 지 아는 경우에 사용하고, while문은 몇 번 반복할지 모를 때 사용한다.
사용 방법은 다른 언어의 그것과 동일하게 while 다음에 조건식, 실행할 코드 블록을 쓰면 된다.
var count = 5;
repeat { // 적어도 한 번은 실행
count += 1 // count++는 안 됨...
print(count)
} while count < 5
/* 실행 결과
6
*/
스위프트에서는 do ~ while 문은 없고 repeat ~ while 문이 있다. do ~ while문처럼 일단 repeat 블록의 내용을 한 번 수행하고 조건에 맞는지 확인하여 조건에 맞으면 반복 실행 한다. 위의 경우는 이미 조건이 거짓이지만 한 번은 실행하므로 count에 1이 더해져서 출력되었다.
for var i in 1..<5 {
if i == 4 break // 한줄에 작성함
else print(i) // 한줄에 작성함
}
/* 실행 결과
main.swift:2:15: error: expected '{' after 'if' condition
if i == 4 break
^
main.swift:1:9: warning: variable 'i' was never mutated; consider removing 'var' to make it constant
for var i in 1..<5 {
~~~~^
*/
반복문이나 조건문에서 한 줄이라도 중괄호를 생략하면 안 된다.
for var i in 1..<5 {
if i == 4 { // i가 4일 때 탈출
break
}
else {
print(i)
}
}
/* 실행 결과
1
2
3
*/
조금 귀찮더라도 한 줄인 문장도 중괄호로 감싸주도록 하자.
for var i in 1..<5 {
if i % 2 == 0 { // 2의 배수는 통과
continue
}
else {
print(i)
}
}
/* 실행 결과
1
3
*/
continue를 사용하면 해당 반복은 실행하지 않고 넘어간다. 일반적으로 조건문과 같이 사용한다. 사실 그렇지 않으면 사용하는 의미가 없다...
var aa = true
var bb = false
if aa, bb { // ,는 AND의 의미
print("둘 다 참")
}
if !(aa && bb) { // !(true && false)
print("둘 다 참이 아님")
}
/* 실행 결과
둘 다 참이 아님
*/
,의 의미는 &&(AND)와 동일하다. 두 피연산자가 참이어야 참을 반환한다.
if ~ else 문
var aa = true
var bb = false
if aa, bb { // ,는 AND의 의미
print("둘 다 참")
}
else { // else를 이용해서 거짓일 때 수행
print("둘 다 참이 아님")
}
/* 실행 결과
둘 다 참이 아님
*/
if ~ else문을 이용하여 if문의 조건식이 거짓일 때 else문을 실행하도록 할 수 있다.
다중 if ~ else 문
var aa = 2
if aa % 3 == 0 { // aa가 3의 배수일 때
print("aa는 3의 배수")
}
else if aa % 2 == 0 { // aa가 2의 배수일 때
print("aa는 2의 배수")
}
else { // 그 외의 경우
print("그 외")
}
/* 실행 결과
aa는 2의 배수
*/
다중 if ~ else문을 사용하여 여러 조건을 지정할 수 있다. 만약 조건이 여러 개라면 else if문을 여러 개 작성할 수 있고 마지막의 else문은 써도 되고 안 써도 된다.
let num = 14.6
// 다중 if ~ else
if num < 10 {
print("num은 10 미만")
}
else if 10 <= num && num < 20 {
print("num은 10 이상 20 미만")
}
else if 20 <= num && num < 30 {
print("num은 20 이상 30 미만")
}
else {
print("그 외")
}
/* 실행 결과
num은 10 이상 20 미만
*/
switch ~ case 문
let str = "안녕"
switch str {
case "하이":
print("하이")
case "안녕":
print("안녕")
case "헬로":
print("헬로")
default:
print("바이")
}
/* 실행 결과
안녕
*/
switch ~ case문을 이용하면 다중 if ~ else문 처럼 여러 조건을 처리할 수 있다. 다른 언어에서는 각 case의 마지막 부분에 break를 포함시켜야 밑의 조건들의 문장들도 실행되는 것을 막을 수 있는데 스위프트에서는 break를 생략해도 자동으로 작동된다.
let num : Int = 147
switch num {
case 11: // 11 일 때
print("11")
case 12: // 12 일 때
print("12")
case 13: // 13 일 때
print("13")
default: // 그 외
print("!!!")
}
/* 실행 결과
!!!
*/
147인 조건이 없어서 default의 문장이 실행되었다.
let num : Int = 147
switch num {
case 11:
// 비워두면 안 됨!
case 12:
// 비워두면 안 됨!
case 13:
print("13")
default:
print("!!!")
}
/* 실행 결과
main.swift:4:5: error: 'case' label in a 'switch' must have at least one executable statement
case 11:
^~~~~~~~
break
main.swift:6:5: error: 'case' label in a 'switch' must have at least one executable statement
case 12:
^~~~~~~~
break
*/
주의할 점은 각 case에 한 문장이라도 작성해야 한다는 점이다. 그렇지 않으면 컴파일 에러가 발생한다.
switch ~ case 문 결합
import Foundation
var ff : Double = 5.7
ff = round(ff) // 반올림
switch ff {
case 2, 4, 6, 8, 10:
print("반올림한 값이 2의 배수")
case 1, 3, 5, 7, 9:
print("반올림한 값이 2의 배수가 아님")
default:
print("그 외")
}
/* 실행 결과
반올림한 값이 2의 배수
*/
case문의 조건은 여러 개를 지정해서 사용할 수 있다.
var i : Int = 5
switch i {
case -5, 5:
print("-5이거나 5")
default:
print("그 외")
}
/* 실행 결과
-5이거나 5
*/
여기서의 콤마는 앞서 for문에서 사용했던 AND의 역할과는 달리 OR의 역할을 수행한다.
where절
let str = "가나다가나다"
let pre = str.startIndex // str의 시작 인덱스
switch str.count {
case 4 where str[pre] == "가":
print("\"가\"로 시작하면서 네 글자인 문자열")
case 5 where str[pre] == "나":
print("\"나\"로 시작하면서 다섯 글자인 문자열")
case 6 where str[pre] == "가":
print("\"가\"로 시작하면서 여섯 글자인 문자열")
default:
print("그 외")
}
/* 실행 결과
"가"로 시작하면서 여섯 글자인 문자열
*/
부가적인 조건을 추가하기 위해서는 where절을 사용한다.
위의 예시에서는 문자열의 길이를 기준으로 케이스를 나누고 추가적으로 각 케이스가 "가" 또는 "나"로 시작하는지 검사했다.
let str = "가나다가나다"
for var i in str where i == "다" { // str의 한 글자씩 순회하면서 "다"인 것만 찾음
print(i)
}
/* 실행 결과
다
다
*/
for문에서도 where를 사용 가능하다.
let str = "가나다가"
let pre = str.startIndex // str의 시작 인덱스
switch str.count {
case 4 where str[pre] == "가":
print("\"가\"로 시작하면서 네 글자인 문자열")
fallthrough // break 실행 X
case 5 where str[pre] == "나":
print("\"나\"로 시작하면서 다섯 글자인 문자열")
fallthrough // break 실행 X
case 6 where str[pre] == "가":
print("\"가\"로 시작하면서 여섯 글자인 문자열")
fallthrough // break 실행 X
default:
print("그 외")
}
/* 실행 결과
"가"로 시작하면서 네 글자인 문자열
"나"로 시작하면서 다섯 글자인 문자열
"가"로 시작하면서 여섯 글자인 문자열
그 외
*/
fallthrough를 입력하면 break를 수행하지 않고 밑으로 내려간다.
함수
함수란 어떤 목적을 가진 관련된 코드를 모아놓은 것이다. 외부에서 매개변수를 받아와 사용할 수 있으며, 리턴을 통해 값을 외부로 전달할 수도 있다.
parameter, 인자, 형식 매개변수: 함수 정의 시에 작성한 부분
argument, 인수, 실질 매개변수: 함수 사용 시에 사용하는 값 또는 레퍼런스
Functions | Documentation (swift.org)
Documentation
docs.swift.org
메서드
클래스, 구조체, 열거형 안에 선언된 함수를 메서드라고 부른다.
함수 정의 및 호출
func hi() -> Void { // 함수 정의
print("안녕하세요")
}
hi()
/* 실행 결과
안녕하세요
*/
끝에 Void를 입력하면 리턴값이 없다는 의미이다.
함수를 정의만해서는 실행이 되지 않는다. 함수명()로 호출을 해주어야 한다.
func hi() { // 함수 정의, Void 생략
print("안녕하세요")
}
hi()
/* 실행 결과
안녕하세요
*/
리턴값이 없을 때 -> Void는 생략할 수 있다.
func make(str1 : String, str2 : String) -> String {
return "<---" + str1 + ", " + str2 + "--->"
}
print(make("사과", "바나나")) // 매개변수명 입력 안 함
/* 실행 결과
main.swift:5:11: error: missing argument labels 'str1:str2:' in call
print(make("사과", "바나나"))
*/
함수를 호출할 때 매개변수가 있다면, 매개변수 명을 명시해주어야 한다.
함수 정의 시에는 내부 매개변수명: 자료형, 내부 매개변수명: 자료형 ...으로 정의하면 된다.
func hi() { // 함수 정의, Void 생략
print("안녕하세요")
}
func make(str1 : String, str2 : String) -> String { // 함수 정의, String 반환
return "<---" + str1 + ", " + str2 + "--->"
}
print(make(str1: "사과", str2: "바나나"))
print(type(of: hi))
print(type(of: make))
/* 실행 결과
<---사과, 바나나--->
() -> ()
(String, String) -> String
*/
이렇게 레이블을 같이 작성해주면 정상적으로 함수가 호출되는 것을 볼 수 있다.
그리고 type(of:)를 통해 자료형을 확인할 수 있는데 여기에 함수명을 입력하면 그 함수의 매개변수 타입과 반환 타입을 알 수 있다.
또한 매개변수가 없거나 반환 타입이 없으면 ()로 나타낸다. 빈 튜플이라는 의미이다.
func hi() { // 함수 정의, Void 생략
print("안녕하세요")
}
func make(apple str1 : String, banana str2 : String) -> String { // 함수 정의, String 반환
return "<---" + str1 + ", " + str2 + "--->"
}
print(make(apple: "사과", banana: "바나나"))
/* 실행 결과
<---사과, 바나나--->
*/
외부 매개변수명은 외부에서 함수 호출 시에 사용하는 것으로 내부 매개변수명 앞에 한 칸을 비운 뒤 작성한다.
함수 정의에 외부 매개변수명을 입력했으면 나중에 함수를 호출할 때도 외부 매개변수명을 사용해야 정상적으로 함수를 사용할 수 있다.
func make(str1 : String, str2 : String) -> String {
return "<---" + str1 + ", " + str2 + "--->"
}
print(make(str1: "사과", str2: "바나나"))
/* 실행 결과
<---사과, 바나나--->
*/
만약 외부 매개변수명을 생략했으면 외부 매개변수명은 자동으로 내부 매개변수명으로 사용되게 된다.
func make1(str1 : String, str2 : String) -> String {
return "<---" + str1 + ", " + str2 + "--->"
}
print(make1(str1: "사과", str2: "바나나"))
func make2(apple str1 : String, banana str2 : String) -> String {
return "<---" + str1 + ", " + str2 + "--->"
}
print(make2(apple: "사과", banana: "바나나"))
func make3(_ str1 : String, _ str2: String) -> String {
return "<---" + str1 + ", " + str2 + "--->"
}
print(make3("사과", "바나나"))
func make4(_ str1: String, banana str2 : String) -> String {
return "<---" + str1 + ", " + str2 + "--->"
}
print(make4("사과", banana: "바나나"))
print(type(of: make1))
print(type(of: make2))
print(type(of: make3))
print(type(of: make4))
/* 실행 결과
<---사과, 바나나--->
<---사과, 바나나--->
<---사과, 바나나--->
<---사과, 바나나--->
(String, String) -> String
(String, String) -> String
(String, String) -> String
(String, String) -> String
*/
매개변수를 설정하는 방법은 여러 가지가 있다.
내부 매개변수명만 사용, 외부 매개변수명&내부 매개변수명 모두 사용, 외부 매개변수명 _로 사용, 첫 번째 외부 매개변수만 _로 사용 등이 있다.
마지막 방법을 제일 많이 쓴다.
함수명
func make1(str1 : String, str2 : String) -> String {
print(#function)
return "<---" + str1 + ", " + str2 + "--->"
}
make1(str1: "사과", str2: "바나나")
func make2(apple str1 : String, banana str2 : String) -> String {
print(#function)
return "<---" + str1 + ", " + str2 + "--->"
}
make2(apple: "사과", banana: "바나나")
func make3(_ str1 : String, _ str2: String) -> String {
print(#function)
return "<---" + str1 + ", " + str2 + "--->"
}
make3("사과", "바나나")
func make4(_ str1: String, banana str2 : String) -> String {
print(#function)
return "<---" + str1 + ", " + str2 + "--->"
}
make4("사과", banana: "바나나")
/* 실행 결과
make1(str1:str2:)
make2(apple:banana:)
make3(_:_:)
make4(_:banana:)
*/
함수명은 외부 매개변수 레이블에 따라 달라진다. 함수명 + 외부 매개변수 레이블: + 외부 매개변수 레이블: + ... 이런식으로 구성되어 있다.
func ddd(x: Double) -> Double {
return x * 2
}
func setX(x: Double) -> Void { // Void 생략 가능
xx = x
}
func getX() -> Double {
return x
}
func mul(x: Double, y: Double) -> Double {
return x * y
}
func setXY(Double: x, Double: y) { // Void 생략
xx = x
yy = y
}'공부 > Swift' 카테고리의 다른 글
| [Swift][9주차] Xcode 및 Mac 사용 (0) | 2023.10.30 |
|---|---|
| [Swift][6주차] 클로저, 클래스 (0) | 2023.10.16 |
| [Swift][5주차] 함수(메서드), guard, 일급객체 및 클로저 (0) | 2023.10.02 |
| [Swift][3주차] 연산자와 Optional (0) | 2023.09.18 |
| [Swift][1, 2주차] Swift 들어가기 및 자료형 (0) | 2023.09.11 |