SA성아 2024. 5. 26. 00:25

출처 - https://www.kxcoding.com/course/essential-swift

 

Essential Swift

iOS 앱 개발을 가볍게 시작해 보세요. Swift를 다양한 예제, 상세한 설명과 함께 정복할 수 있습니다. 문법적 기초가 튼튼해야 원하는 기능을 자유롭게 구현할 수 있습니다.

www.kxcoding.com

아래 내용들은 KxCoding의 essential-swift강의를 보고 작성되었습니다. 

 

Working with Variables

변수(Variable)

어떤 값을 저장하는 공간

언제든지 새로운 값을 저장할 수 있다. 

var variableName(변수이름) = initialValue(초기값) //=: Assignment Operator(할당연산자)
var name = "Swift" // Swift라는 문자열 값이 name라는 변수에 저장
                   // "Swift": String Literal(문자열 리터럴)
var thisYear = 2024
var valid = true

name //메모리에 저장된 값을 읽어오기만 함, 의미 X
print(name) //실제 프로젝트에서 저장된 값을 확인할 때는 print나 dump함수 이용

 

variableName = initialValue //변수에 새로운 값 저장
name //Ambiguous use of 'name'
print(name) //Ambiguous use of 'name'
var name = "Steve" //err, Invalid redeclaration of 'name'

name = "Steve" //변수에 저장되어있는 값이 새로운 값으로 바뀜
name = "윤아"

print(name) //윤아

var anotherName = name
anotherName = "Tim"

print(name, anotherName) //윤아, Tim
//변수의 값을 바꿔도 다른 변수의 값은 바뀌지 않음

thisYear = "2024" //err, Cannot assign value of type 'String' to type 'Int'

상수(Constant)

let constantName = initialValue
let name = "Yoona"
name

name = "Steve" //err, Cannot assign to value:'name' is a 'let' constant
//상수는 한 번만 저장이 가능하고 그 다음부터는 읽기만 가능하다

 

 

Naming Convention

CamelCase

이름에 포함된 첫번째 문자를 표기하는 방법, 두 개 이상의 단어가 포함되어 있을때 단어를 구분하는 방법 규정

케이스 유형 설명 예시 적용되는 항목
UpperCamelCase 이름에 포함된 모든 첫 번째 문자를 대문자로, 나머지는 모두 소문자로 함. Name, BookIndex, MemberNumber, CreditCard, UserStatusCode Class, Structure, Enumeration, Extension, Protocol
lowerCamelCase 첫 번째 문자는 항상 소문자, 나머지는 UpperCamelCase와 같음. name, bookIndex, memberNumber, creditCard, userStatusCode Variable, Constant, Function, Property, Parameter

 

 

Scope(범위)

Global Scope(전역범위)

어떤 브레이스에도 속하지 않음

딱 하나밖에 없다

Local Scope(지역범위)

무조건 브레이스 안에 있음

여러 단계로 중첩 가능 -> 두 개 이상 존재 가능

Declaration Scope(선언범위)

import UIKit

// #1 Global Scope
let g1 = 23 //Global Scope안에서 더이상 g1이라는 이름은 사용할 수 없음

func doSomething() {

    // #3 Local Scope
    let local1 = 123
    let g1 = 789

    if true {
        // #4 또 다른 Local Scope
        let local3 = 123
    }

    // #5 Local Scope
    let local2 = 123
}

// #2 Global Scope
let g2 = 456

struct Scope {
    // #6 Declaration Scope
    var a = g1

    func doSomething() {
        // #7 Declaration Scope안에 있는 Local Scope

    }
}

#1, #2 둘 다 어떤 브레이스에도 속하지 않는 Global Scope
#3, #4 둘다 Local Scope에 있지만 4번이 3번 아래에 포함되어있음
#3, #5는 동일한 함수 내부에 있고 깊이도 동일 -> 동일한 로컬 스코프

 

규칙
1. 동일한 스코프에 접근할 수 있다.
2. 글로벌 스코프에서는 선언 순서에 상관없이 접근할 수 있다.
3. 로컬 스코프에서 상위 스코프나 글로벌 스코프에 접근할 수 있다.
4. 글로벌 스코프가 아니라면 이미 선언되어있는 요소에만 접근할 수 있다.
5. 상위 스코프는 하위 스코프에 접근할 수 없다.
6. 서로 다른 스코프에 동일한 이름이 존재한다면 가장 가까운 스코프에 있는 이름을 사용한다.
7. 글로벌 스코프가 아닌 다른 모든 스코프는 시작과 끝이 명확해야 한다.

 

 

Literals, Data Types

메모리의 구조와 크기

Memory

0과 1을 저장할 수 있는 반도체

전기가 들어오면 1, 들어오지 않으면 0 저장

Bit

0이나 1을 저장할 수 있는 가장 적은 공간, 정보의 기본 단위

Byte

bit가 8개 모인 공간, 프로그래밍 언어에서 사용하는 기본 단위

양수: 0 ~ 255, 양수와 음수 모두: -1328 ~ 127 까지 저장 가능

ex) 22 -> 00010110

더보기
더보기

Most Significant Bit            Least Significant Bit

MSB                                                        LSB

   0       0       0       1       0       1       1       0

<---------------------------------------->

                              Data Bit

Singed와 Unsigned

Signed 음수와 양수, 숫자 0을 모두 저장할 수 있는 타입
Unsigned 음수는 저장하지 않고 양수와 0만 저장

 

Sing Bit

최상위 비트에 저장된 값 0 양수(Positive Number)
1 음수(Negative Number)

 

2's Complement

양수의 비트값을 반전시킨 다음 1을 더해 음수를 표현하는 방식

ex) 22  ----->  0 0 0 1 0 1 1 0  --Bitwise Not-->  1 1 1 0 1 0 0 1 --+1--> 11101010

더보기
더보기

MSB                                                      LSB

   1       1       1       0       1       0       1       0

 Sign  <------------------------------->

  Bit                         Data Bit

실수를 저장하는 방법

1. 실수를 저장할 때는 지수와 가수로 나눠서 저장한다.

2. 동일한 메모리 크기에서 정수보다 더 넓은 범위를 저장할 수 있다

3. 부동 소수점에는 오차가 있어서 100% 정확한 값을 저장할 수 없다 

 

Data Types

Built-in Data Type
Integer Type 정수 저장
Floating-Point Type 소수점이 포함된 수를 저장
Boolean Type 참과 거짓 저장
Character Type 하나의 문자를 저장
String Type 0개 이상의 문자 저장 

 

Custom Data Type

구조체와 클래스로 직접 만드는 자료형

 

Numbers

Number Literal

123 //정수 리터럴

+123 //양수, +기호 생략가능
-123 //음수, -기호 생략 불가능
1.23 //실수, 정수 부분 생략 불가능

1.23e4 //10진수 실수는 지수의 형태로 표현할 수 있음
0xAP2  //16진수 실수

1_000_000 //금액 표시, ,대신 _사용

0b1010 //10진수 10 2진수로 표현
0o12   //8진수로 표현
0xA    //16진수

 

Integer Type

Int8.min    //-128
Int8.max    //127

Int16.min   //-32,768
Int16.max   //32,767

Int32.min   //-2,147,483,648
Int32.max   //2,147,483,647

Int64.min   //-9,223,372,036,854,775,808
Int64.max   //9,223,372,036,854,775,807

 

Signed vs Unsigned

더보기
더보기

    Int8                UInt8

    Int16              UInt16

    Int32             UInt32

    Int64             UInt64

  Signed          Unsigned

Floating-point Type

Float: 4byte

Double: 8byte

let f: Float = 3.141592653589793238462643383279502884197169
let d: Double = 3.141592653589793238462643383279502884197169

print(String(format: "%.20f", f)) //3.14159274101257324219
print(String(format: "%.20f", d)) //3.14159265358979311600

정수를 사용할 때는 Int, 실수를 사용할때는 Double을 사용

 

Boolean

Boolean Literal

true, false 두 개뿐이고 모두 소문자로 써야함

let happy = true
let happy = false

let isHappy: Bool = true

let str = ""
str.isEmpty

 

Strings and Characters

String Literal, 문자열 타입과 문자 타입 

"Have a nice day"

"123"

let str = "1"
type(of: str) // String.Type

let ch: Character = "1"
type(of: ch) //Character.Type

//let doubleCh: Character ="AA" // err

let emptyCh: Character = " " //Character Type에 빈 문자를 저장하고 싶으면 하나의 공백으로 저장해야 한다

 

Type Inference

Type Inference

let num = 123
type(of: num) //Int.Type

let temp = 11.2
type(of: temp) //Double.Type

let str = "Swift"
type(of: str) //String.Type

let a = true
let b = false
type(of: a) //Bool.Type
type(of: b) //Bool.Type

 

Type Annotation

let name: Type = value
var name: Type = value
let num: Int = 123

let value: Double
value = 12.3

 

Type Inference Rules

123 Int
1.23 Double
"Hello" String
true Bool
false Bool

 

 

Operators

Operator Basics

연산자와 피연산자

a + b

+: Operator

a, b: Operand

 

피연산자 수에 따른 분류

+a Unary Operator(단항 연산자)
a + b Binary Operator(이항 연산자)
a ? b : c Ternary Operator(삼항 연산자)

 

연산자와 공백 

단항 연산자 +a o
+  a x
이항 연산자 a + b o
a+b o
a  +b x
a+  b x
삼항 연산자 a ? b : c o

 

연산자 위치에 따른 분류

단항 연산자 +a Prefix Operator(전치 연산자)
a+ Postfix Operator(후치 연산자)
이항 연산자 a + b Infix Operator(중치 연산자)

 

연산자 우선순위

더보기
더보기

a + b * c

      -----1

---------2

곱하기 연산자의 우선순위가 더하기보다 높다

Precedence

더보기
더보기

( ( ( a + b ) * c ) - d ) * e

가장 안쪽에 있는 ( )가 우선순위가 높음

 

연산자 결합규칙

Left Associative 왼쪽부터 계산
Right Asscoiative 오른쪽부터 계산

 

Arithmetic Operator

+연산자 

let a = 12
let b = 34

 

Plus

+a //12
a + b //46

12 + 34
a + 34

 

Minus

-a //-12
-b //-32

a - b //-22

 

Multiplication

a * b //408

 

Division

a / b //0
b / a //2

let c = Double(a)
let d = Double(b)

c / d //0.3529411764705883
d / c //2.833333333333333

 

Remainder

a % b //12

c % d //err, 실수 연산은 지원하지 않음
c.truncatingRemainder(dividingBy: d) //12

 

overflow

let num: Int8 = 9 * 9 //81

//let num2: Int8 = 9 * 9 * 9 //err, overflow
let num2: Int = 9 * 9 * 9 //729

 

Comparison Operators

let a = 12
let b = 34

 

Equal to Operator

a == b //false

"swift" == "Swift" //false

 

Not equal to Operator

a != b //true

 

Greater than Operator

a > b //false

"swift" > "Swift" //true

 

Greater than or equal to Operator

7 >= 7 //true

 

Less than Operator

a < b

 

Less than or equal to Operator

a <= b

 

 

Logical Operators

!연산자 

let a = 12
let b = 34

 

Logical Not Operators

!a //err

!true  //false
!false //true

a < b //true
!(a < b) //false

 

Logical AND Ooerators

a > 10 && b > 10  //true
a > 100 && b > 10 //false

true && true	  //true
true && false	  //false
false && true     //false
false && false    //false

 

Logical OR Operators

true || true	  //true
true || false	  //true
false || true     //true
false || false    //false

 

Ternary Conditional Operator

condition ? expr1 : expr2

let hour = 12

hour < 12 ? "오전" : "오후"  //오후
hour < 12 ? 123 : 456 	   //456

hour < 12 ? 123 : "456"    //err

 

Assignment Operators

할당 연산자 

let a = 12 //왼쪽 피연산자는 항상 메모리 공간을 가지고 있어야 함

12 = 12   //err
12 + 3    //err

var b = 12
b = 34   //할당연산자가 결과를 리턴하지 않음

LValue

할당 연산자 왼쪽에서 메모리 공간을 나타내는 표현식

RValue

할당 연산자 오른쪽에서 저장할 값을 나타내는 표현식

 

Compaound Assignment Ooperators

Addition Assignment Operator

var a = 0

a = a + 1
a += 1     //위와 같은 코드

 

Subtraction Assignment Operator

a -= b
a = a - b

 

if Statement

if 문

조건의 참과 거짓을 판단한 다음에 실행한 코드를 결정

 

if condition { 
	statements 
} //Condition == 조건 ==Boolean

결과가 true면 if블록을 실행하고 false이면 실행하지 않음

 

ex) 간단한 로그인 코드

let id = "root" 
let password = "1234qwer" 
if id == "root" { 
	print("valid id") 
} 
if password == "1234qwer" { 
	print("valid password") 
} 

if id == "root" && password == "1234qwer" { 
	print("go to admin page") 
}


if-else 문

if condition{ 
	statements 
} else { 
	statements 
}

 if블록이 false이면 else문 실행 

if id == "root" && password == "1234qwer" {
    print("go to admin page")
} else {
    print("incorrect value")
}

 

if-else if 문

if condition {
    statements //if 블록, 항상 처음에. 하나만. 필수
} else if condition {
    statements // else if 블록, 두 블록 사이에. 하나 이상. 생략 가능 
} else {
    statements //else 블록, 항상 마지막에. 하나만. 생략 가능 
}
let num = 123

if num >= 0 {
    print("Positive number or zero") //실행
} else if num % 2 == 0 && num >= 0 {
    print("positive even number")
} else if num % 2 == 1 && num >= 0 {
    print("positive odd number")
} else {
    print("negative number")
}

위의 코드는 문제가 두 가지가 있다

  1. 조건이 중복되고 있음
  2. if의 condition과 나머지 else if에 있는 condition이 겹치고 있음
let num = 123

if num >= 0 {
    print("Positive number or zero") //실행
    if num % 2 == 0 {
        print("positive even number")
    } else if num % 2 == 1 {
        print("positive odd number") //실행 
    } 
} else {
    print("negative number")
}

위의 문제를 수정한 코드 

 

let num = 123

if num > 0 {
    print("positive number")
} else if num > 10 {
    print("positive number over 10")
} else if num > 100 {
    print("positive number over 100")
}

무조건 첫번째 if문만 동작

let num = 123

if num > 100 {
    print("positive number over 100")
} else if num > 10 {
    print("positive number over 10")
} else {
    print("positive number")
}

위의 문제를 수정한 코드

 

guard Statement

gurad문

if문과 마찬가지로 condition을 평가한 다음에 실행한 코드 결정

guard condition else { 
	statements
}

guard optionalBinding else {
	statements
}

else문 생략 불가능, 반드시 else문 안에서 스코프를 종료해야 함

 

import UIKit

func validate(id: String){
    guard id.count >= 6 else {
        print("too short")
        return
    }
    print("OK")
}

validate(id: "short") //함수 호출

 

실행 결과: too short

import UIKit

func validate(id: String){
    guard id.count >= 6 else {
        print("too short")
        return
    }
    print("OK")
}

validate(id: "kxcondingAdim")

실행 결과: OK 

import UIKit

func validate(id: String){
    guard id.count >= 6 else {
        print("too short")
        return
    }
    
    guard id.count <= 20 else {
        print("too long")
        return
    }
    print("OK")
}

validate(id: "kxcondingAdimdfasfhkafdskjfdhakjdhfjkahfdkjhafkj")

실행 결과: too long

 

위의 코드 if문으로 구현

func validateUsingIf(id: String){
    if id.count >= 6 {
        if id.count <= 20 {
            print("OK")
        } else {
            print("too long")
        }
    } else {
        print("too short")
    }
}

 

switch Statement

switch 문

값을 비교한 다음에 값이 일치하면 코드를 실행

switch valueExpression {
case pattern:
	statements
case pattern, pattern:
	statements
default:
	statements
}

 

ex)

let num = 1

switch num {
case 1: 
	print("one")
case 2, 3:
	print("two or three")
default:
	break
}

 

switch valueExpression {
case pattern:
	statements
case pattern where condition:
	statements
default:
	statements
}

위처럼 where절 추가도 가능하다

 

Interval Matching

let temperature = Int.random(in: -10 ... 30) //범위연산자, -10에서 30 사이의 값을 만듦

switch temperature {
case ...10: //10 이하의 값 매칭 
    print("cold")
case 11...20: //11부터 20까지 매칭
	print("cool")
case 21...27:
	print("warm")
case 28...:
	print("hot")
default:
	break
}

 

Fall Through

다음 case로 이동

let attempts = 10

switch attempts {
case ...9:
    print("warning")
case 10:
    print("locked")
    fallthrough
default:
    print("send warning email")
}

실행 결과: locked

                send warning email