
출처 : smileHan - iOS 프로그래밍기초
Swift문법의 주의사항
1. 양쪽에 일관된 공백 필요.
var x = 10
pring(x) // 출력 : 10
let x = 10
pring(x) // 출력 : 10
변수나 상수 명은 영문자, 숫자, Unicode(이모티콘, 중국어, 한글 등)도 가능합니다.
이것은 변수를 선언할 때 명시적으로 타입을 지정하지 않아도, 컴파일러가 변수의 초기 값을 기반으로 자동으로 타입을 결정하는 기능입니다.
보통 코드를 작성할땐 데이터의 타입을 지정하지않고 사용합니다.(타입추론 사용)
Bool
타입추론 기본값 : true
Character
타입추론 불가
문자, 숫자, 문장 부호, 심볼 같은 유니코드(Unicode)문자 하나를 저장
주의 : 초깃값은 작은 따옴표가 아니고 큰 따옴표
Int
정수형 초깃값일때 타입추론
양수, 음수, 영(0) 값을 담을 수 있는 부호 있는 정수
Int8, Int16, Int32, Int64 지원
Float
타입추론 불가
32비트로 부동 소수점 수를 저장, 소수점 6자리 정밀도
Double
실수형 초깃값일때 타입추론
64비트로 부동 소수점 수를 저장, 소수점 15자리 정밀도
String
문자형 초깃값일때 타입추론
단어나 문장을 구성하는 일련의 문자
저장, 검색, 비교, 문자열 연결, 수정 등의 기능을 포함
var x : Int = 10
let Min : Int32 = -2147483648
let Max : Int32 = 2147483647
var str = "type inference"
print(x); // 출력 : 10
print("x"); // 출력 : x
// 문자열 내부에 변수나 상수를 사용하고 싶을땐 \(출력하고 싶은 변수나 상수) 사용
print("\(x)"); // 출력 : 10
print("값은 \(x)입니다.") // 출력 : 값은 10입니다.
print("Int32 Min = \(Int32.min) Int32 Max = \(Int32.max)")
// 출력 : Int32 Min = -2147483648 Int32 Max = 2147483647
print("타입 추론 발동! \(str) <- String형")
// 자료형의 크기가 궁금할 경우 - size(ofValue: ?)
let x_s = MemoryLayout.size(ofValue: x)
let Min_s = MemoryLayout.size(ofValue: Min)
let Max_s = MemoryLayout.size(ofValue: Max)
print(x_s) // 출력 : 8
print(Min_s) // 출력 : 4
print(Max_s) // 출력 : 4
print(type(of:x)) // 해당 변수나 상수의 데이터 타입을 알려준다.
let s = MemoryLayout.size(ofValue: x) // 해당 변수나 상수의 데이터 값을 알려준다.
let t = MemoryLayout<Int>.size // Int형의 데이터 값을 알려준다.
print(s, t)
// Double형
var myWeight : Double
myWeight = 58.5
// Float형
// 주의사항! 실수값으로 초깃값을 준다면 Double형으로 타입추론합니다.
var myHeight : Float
myHeight = 178.5
// Bool형
var orangesAreOrange : Bool
orangesAreOrange = true
// Character형
var myChar1 : Character
var myChar2 : Character = ":"
var myChar3 : Character = "X"
// String형
var userName : String = "Kim"
여러 값을 하나의 개체에 일시적으로 묶는 방법
튜플에 저장되는 항목들은 어떠한 타입도 될 수 있으며, 저장된 값들이 모두 동일한
타입일 필요도 없다.
튜플의 가장 강력한 점은 함수에서 여러 값들을 한 번에 반환하는 것입니다.
// Tuple
// 1개의 값당 이름을 할당
let myTuple = (myInt : 10, myFloat : 12.1, myString : "Hi") //과제 : myTuple의 자료형
print(type(of:myTuple))
// 출력 : (myString: Int, myFloat: Double, myInt: String)
// 이름없이 값 할당
let myTuple2 = (10, 12.1, "Hi")
print(type(of:myTuple2))
// 출력 : (Int, Double, String)
// 데이터 접근 방식
print(myTuple.myInt, myTuple.1)
// 출력 : 10 12.1
값을 반환할 때 오류가 발생할 가능성이 있는 값은 옵셔널 타입이라는 객체로 감싸서 반환함
변수 또는 상수에 아무런 값이 할당되지 않는 상황을 안전하게 처리하기 위한 방법 제공
옵셔널형 선언 : 자료형 뒤 ?
옵셔널 언래핑 : 변수명 뒤 !
// Optional
var op_x : Int? //옵셔널 정수형 변수 x 선언
var y : Int = 0
print(op_x) // 출력 : nil
op_x = 10
print(op_x) // 출력 : Optional(10)
print(op_x!) // forced unwrapping해서 10이 나옴
//op_x = op_x+2 // 불가능
//y = op_x // 불가능
// forced unwrapping
// 주의 : if x!=nil 이라고 쓰면 안됨
op_x = 10
if op_x != nil {
print(op_x!)
}
else {
print("nil")
}
var op_x1 : Int?
if op_x1 != nil {
print(op_x1!)
}
else {
print("nil")
}
// Optional binding
var op_a : Int?
var op_b : Int?
op_a = 100
op_b = 200
if let u_op_a = op_a{
//옵셔널 변수가 값이 있다면 언래핑해서 일반 상수 u_op_x에 대입하고 if문 실행
//값이 없다면 if문의 조건이 거짓이 되어 if문을 실행하지 않는다.
print("Optional binding 성공")
print(u_op_a, op_a)
}else{
print("nil")
}
if let u_op_b = op_b{
print("두개를 한번에 Optional binding 성공")
print(u_op_b, op_b)
}else{
print("nil")
}
// 과제
// 출력 : cat dog
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let pet1, let pet2 {
print(pet1, pet2)
} else {
print("nil")
}
var age : Int?
age = 20
print(age) // 출력 : Optional(20)
var myAge = age ?? 1
print(myAge) // 출력 : 20
// 여러가지 언래핑
var c : String? = "Hi" // 실습 : ""이면 프린트문 공백출력
//forced unwrapping
print(c,c!)
// 출력 : Optional("Hi") Hi
// optional binding
if let a = c{
print(a)
}
// 출력 : Hi
// nil coalescing operator
let c1 = c ?? ""
print(c1)
// 출력 : Hi
// optional chaining
let c2 = c!.count
print(type(of: c2), c2)
// 출력 : Int 2
let c3 = c?.count
print(type(of: c3), c3, c3!)
// 출력 : Optional<Int> Optional(2) 2
옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑이 되도록 선언할 수도 있다.
클래스의 아웃렛 변수 초기화에서 많이 사용
강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근 가능
암묵적인 언래핑으로 옵셔널을 선언하기 위해서는 선언부에 물음표(?) 대신느낌표(!)를 사용
// 암묵적 언래핑
let aa : Int! = 1
let bb : Int = aa
let cc : Int = aa!
let dd = aa
let ee = aa + 1
print(aa,bb,cc,dd,ee)
// 출력 : Optional(1) 1 1 Optional(1) 2
print(type(of:aa),type(of:bb),type(of:cc),type(of:dd), type(of:ee))
// 출력 : Optional<Int> Int Int Optional<Int> Int
// Implicitly Unwrapped Optional를 이용한 클래스
class MyAge {
var age : Int!
init(age: Int) {
self.age = age
}
func printAge() {
print(age) //optional(1)
print(age+1) //2, age! + 1 라고 쓰지 않아도 됨
let age1 : Int = age
print(age1) //1
let age2 = age + 2
print(age2) //3
}
}
var han = MyAge(age:1)
han.printAge()
옵셔널 변수에 값이 없을 때 할당하는 값이다.
상수나 변수가 값이 없는 상태가 존재한다면 옵셔널 타입으로 선언
옵셔널 변수에 초깃값을 할당하지 않으면 자동으로 nil이 할당된다.
public enum Optional<Wrapped> {
case none
case some(Wrapped)
}//실습시 아래 소스만 작성
var xx: Int? = .some(20) // Optional.some(20)
var yy: Int? = .some(10) // Optional.some(10)
var zz: Int? = .none // Optional.none
var xx1: Optional<Int> = .some(30) // Optional.some(30)
print(xx, yy, zz, xx1) // 출력 : Optional(20) Optional(10) nil Optional(30)
위 코드 열거형에선 2가지 경우가 있습니다.
1. .some(Wrapped): 값을 포함한 상태
2. .none: 값이 없는 상태 (nil과 동일)
xx, yy : Int? 타입(옵셔널 정수)이며, .some(값)을 사용해 값을 저장
zz : .none이므로 값이 없음 (즉, nil과 동일)
xx1 : Optional로 선언되었으며, Optional.some(30)을 저장
대입 연산자
왼쪽에 있는 피연산자는 값이 할당되는 변수 또는 상수이며, 오른쪽에 있는 피연산자는 할당할 값
복합 대입 연산자
연산자를 사용한 연산이 끝난 후 다시 왼쪽에 있던 변수나 상수에 할당
산술 연산자
보통 두 개의 피연산자를 받는 이항(binary) 연산자
비교 연산자
비교의 결과로 불리언(Boolean) 값을 반환
논리 연산자
NOT(!), AND(&&), OR(||)와 XOR(^)
삼항 연산자
비교 연산을 빠르게 하기 위한 연산자
나머지 연산자는 아래 코드에서 정리하겠습니다.
// 대입 연산자
var d_x : Int? // 옵셔널 Int 변수를 선언
var d_y = 10 // 일반 Int 변수를 선언하고 초기화
d_x = 10 // 출력 : Optional(10)
d_x = d_x! + d_y // 출력 : Optional(20)
d_x = d_y // 출력 : Optional(10)
// 산술 연산자
var s_x : Int?
var s_y = -20 // 단항 -> 값을 음수로 할당
s_x = 20
print(s_x! + s_y) // 덧셈 출력 : 0
print(s_x! - s_y) // 뺄셈 출력 : 40
print(s_x! * s_y) // 곱셈 출력 : -400
print(s_x! / s_y) // 나눗셈 출력 : -1
print(s_x! % s_y) // 나머지 출력 : 0
// 복합 대입 연산자
var bh1 = 100
var bh2 = 10
bh1 += bh2 // 설명 : bh1와 bh2를 더하고 그 결과를 bh1에 할당
print(bh1)
// 출력 : 110
bh1 -= bh2 // 설명 : bh1와 bh2를 빼고 그 결과를 bh1에 할당
print(bh1)
// 출력 : 100
bh1 *= bh2 // 설명 : bh1와 bh2를 곱하고 그 결과를 bh1에 할당
print(bh1)
// 출력 : 1000
bh1 /= bh2 // 설명 : bh1와 bh2를 나누고 그 결과를 bh1에 할당
print(bh1)
// 출력 : 100
bh1 %= bh2 // 설명 : bh1와 bh2의 나눈 나머지를 bh1에 할당
print(bh1)
// 출력 : 0
bh1 &= bh2 // 설명 : bh1와 bh2의 bit AND연산 결과를 bh1에 할당
print(bh1)
// 출력 : 0
bh1 |= bh2 // 설명 : bh1와 bh2의 bit OR연산 결과를 bh1에 할당
print(bh1)
// 출력 : 10
// 비교 연산자
let b1 = 10
let b2 = 20
print(b1 == b2) // b1와 b2가 같다면 true를 반환
// 출력 : false
print(b1 != b2) // b1와 b2가 같지 않다면 true를 반환
// 출력 : true
print(b1 > b2) // b1가 b2보다 크면 true를 반환
// 출력 : false
print(b1 < b2) // b1가 b2보다 작으면 true를 반환
// 출력 : true
print(b1 >= b2) // b1가 b2보다 크거나 같으면 true를 반환
// 출력 : false
print(b1 <= b2) // b1가 b2보다 작거나 같으면 true를 반환
// 출력 : true
// 논리 연산자
let n1 = true
let n2 = false
print(n1 && n2) // n1과 n2가 true일때 ture를 반환
// 출력 : false
print(n1 || n2) // n1와 n2 둘중에 1개만이라도 true일때 ture를 반환
// 출력 : true
print(!n1) // n1이 false라면 true를 반환
// 출력 : false
// 범위 연산자
1...5 // 1부터 5까지
1..<5 // 1부터 4까지
// 숫자를 변수로 대체할 수 있음
// One-Sided Ranges
let names = ["A", "B", "C", "D"]
for name in names[..<2] {
print(name)
}
// 과제 실행 결과
// 2... 출력 : C D
// ...2 출력 : A B C
// ..<2 출력 : A B
// 삼항 연산자
let num1 = 10
let num2 = 20
let result = num1 > num2 ? num1 : num2
print(result)
// 출력 : 20
// 부가설명 : num1 > num2를 비교했을때 true면 num1반환 아닐 경우 num2반환
for 상수명 in 컬렉션 또는 범위 {
// 실행될 코드
}
// '상수명'은 반복문이 돌면서 컬렉션 또는 범위에서 가져온 항목을 담을 상수
for index in 1...5 {
print(index)
}
// '컬렉션 또는 범위'는 반복문이 반복되면서 현재의 항목을 참조
// 'index'라는 상수에 현재 항목 할당
// 출력 : 1 2 3 4 5
// 만약 상수가 필요없다면 _로 생략가능
for _ in 1...5 {
print("Hi")
}
let names = ["A", "B", "C", "D"]
for name in names {
print(name)
}
// 출력 : A B C D
for (키 상수명, 밸류 상수명) in 딕셔너리명 {
print("\(키 상수명)s have \(밸류 상수명) legs")
}
let numberOfLegs = ["Spider": 8, "Ant": 6, "Dog": 4]
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}
while 조건식 {
// 반복 코드
}
var myCount = 0
while myCount < 1000 {
myCount += 1
}
print(myCount)
// 출력 : 1000
repeat {
//
} while 조건식
var i = 10
repeat {
i=i-1
print(i)
} while (i > 0)
// 출력 : 9 8 7 6 5 4 3 2 1 0
// break
for i in 1..<10 {
if i > 5{ // i가 5보다 클 경우
break
}
print(i)
}
// 출력 : 1 2 3 4 5
보통은 if문 한 줄일 경우는 "{}"를 안 넣지만 break문 사용 시 한 줄이라도 "{}"필수입니다.
// continue문
for i in 1...10 {
if i % 2 == 0 { i와 2의 나머지값이 0일 경우
continue
}
print(i)
}
// 출력 : 1 3 5 7 9
if 불리언 표현식 {
// 불리언 표현식이 참일 경우 수행될 코드
}
var if_x = 10
if if_x > 5 {
print("5보다 큽니다")
}
// 출력 : 5보다 큽니다
// 조건 나열(condition-list)
if_x = 1
var if_y = 2
if if_x == 1 && if_y == 2 { //논리식이 둘 다 참일 때
print(if_x,if_y)
}
if if_x == 1, if_y == 2 { //조건이 둘 다 참일 때, 두 조건을 콤마로 연결한다
print(if_x,y)
}
var if_a : Int? = 1
var if_b : Int? = 2
print(if_a, if_b)
if let if_a1 = if_a, let if_b1 = if_b { //a와 b가 nil이 아니면, 언래핑하여 a1과 b1에 대입
print(if_a1,if_b1)
}
if 불리언 표현식 {
// 표현식이 참일 경우 실행되는 코드
} else {
// 표현식이 거짓일 경우 실행되는 코드
}
var ie_x = 3
if ie_x % 2 == 0 {
print("짝수입니다")
}else{
print("홀수입니다")
}
// 출력 : 홀수입니다.
// 다중 if문
// 다양한 조건을 바탕으로 결정해야 할 때 다중 if-else구문을 사용
var num = 3
if num == 1 || num == 3 {
print("당신은 남성이군요!\n")
}else if num == 2 || num == 4 {
print("당신은 여성이군요!\n")
}else {
print("당신은 대한민국 사람이 아니군요!\n")
}
아래 코드는 if문 정리 코드입니다.
// if문 최종 코드
let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001) // kg/m*m
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(bmi), 판정:\(body)")
// 출력 : BMI:20.761245674740483, 판정:정상
위 코드를 switch-case문으로 변경 시
switch 표현식
{
case match1:
구문
case match2:
구문
case match3, match4:
구문
default:
구문
}
// switch-case문
var value = 0
switch (value)
{
case 0: // value가 0일때 실행
print("영")
case 1: // value가 1일때 실행
print("일")
case 2: // value가 2일때 실행
print("이")
case 3: // value가 3일때 실행
print("삼")
default: // case문이 실행되지 않았을 때 실행
print("4이상")
}
// 출력 : 영
let someCharacter: Character = "z"
switch someCharacter {
case "a": // someCharacter가 "a"일때 실행
print("someCharacter : a")
case "z": // someCharacter가 "b"일때 실행
print("someCharacter : z")
default: // case문이 실행되지 않았을 때 실행
print("이건 뭐지?")
}
// 출력 : someCharacter : z
아래 코드와 같이 ,(콤마)를 사용해 여러 가지 다른 경우에 대해서 그룹 case 문을 만들 수 있습니다. 또한 범위 연산자를 사용해 case문을 유연하게 사용 가능합니다.
// 콤마를 사용한 switch-case문
var value1 = 3
var days : Int = 0
switch(value1)
{
case 1,3,5,7,8,10,12:
print("31 일입니다")
case 4,6,9,11:
print("30 일입니다")
case 2:
print("28 or 29 일입니다")
default:
print("월을 잘못 입력하셨습니다")
}
// 출력 : 31
// 범위 연산자를 사용한 switch-case문
let number = 25
let count : String
switch number {
case 0...9:
count = "한자리 수"
case 10...99:
count = "두자리 수"
case 100...999:
count = "세자리 수"
default:
count = "네자리 수 이상"
}
print("\(count)입니다.")
// 출력 : 두자리 수
var value2 = 4
switch (value2)
{
case 4:
print("4")
fallthrough
case 3:
print("3")
fallthrough
case 2:
print("2")
fallthrough
default:
print("1")
}
// 출력 : 5 4 3 2 1
// 기본 where절
var numbers: [Int] = [1, 2, 3, 4, 5]
for num in numbers where num > 3 {
print(num) // num이 3보다 클 경우 출력
}
// 출력 : 4 5
과제 : where절 예제 하나 만들기
let numbers1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for number in numbers1 where number % 2 != 0 {
print(number)
}
for문에 where절을 부여
number를 2를 나눴을 때 나머지가 0이 아닐 경우 number를 출력

func <함수명> (<매개변수 이름>: <매개변수 타입>, <매개변수 이름>: <매개변수 타입>,... ) -> <반환값 타입> {
// 함수의 기능
}
func sayHello() { //리턴값 없으면( -> Void ) 지정하지 않아도 됨
print("Hello")
}
sayHello() // 호출
// 출력 : Hello
// 하나의 문자열과 하나의 정수를 매개변수로 받아서 문자열을 반환
func message(name: String, age: Int) -> String {
return("이름 : \(name), 나이 : \(age)")
}
print(message(name: "김승현", age: 25)) // 호출
// 출력 : 이름 : 김승현, 나이 : 25
이번엔 C언어의 함수를 Swift의 문법으로 바꿔보겠습니다.
// C,C++
int add(int x, int y){
return(x+y);
}
printf("%d", add(10, 20));
// 출력 : 30
// Swift
func add(x: Int, y: Int) -> Int {
return(x+y)
}
print(add(x:10, y:20)) // 출력 : 30
print(type(of:add)) // (Int, Int) -> Int
// 설명 : 매개변수의 이름은 x,y이고 둘다 정수형이다.
//반환값은 정수형으로 반환
//기능은 매개변수로 받은 값들을 덧셈하여 반환해준다.
//그 후 출력.
그리고 type(of:_) 내장함수를 사용하면 그 값의 자료형을 알 수 있습니다.
바로 위의 add함수의 자료형을 알고싶다면 저렇게 작성하면 됩니다.