[Swift 야곰] 1단원. 스위프트 기초

Jamong·2023년 1월 3일
0

프로그래머스 코딩테스트 입문 문제를 풀면서 Swift의 기초가 많이 부족하다고 느껴 다시 학습하게 되었다.

BoostCourse의 야곰: iOS 프로그래밍을 위한 스위프트 기초는 기존의 프로그래머 또는 프로그래밍 개념이 있는 사람이 빠르게 스위프트 문법을 익힐 수 있도록 스위프트의 기초적인 핵심문법을 제공하는 강의다.

Swift는 잠깐 사용했었고, 주로 Python을 사용하던 나에게 있어서 알맞는 강의인 것 같아 선택하였다.

학습기간은 2주 정도로 잡았다.
(2023.01.03 ~ 2023.01.17)


Day 1 - 2023.01.03

상수와 변수

상수와 변수의 선언 키워드는

  • 상수 let
  • 변수 var

상수와 변수의 선언은

// 상수의 선언 (차후에 변경이 불가능한 상수)
let 이름: 타입 =// 변수의 선언 (차후에 변경이 가능한 변수)
var 이름: 타입 =
상수와 변수 예제.swift

let constant: String = "차후에 변경이 불가능한 상수 let"
var variable: String = "차후에 변경이 가능한 변수 var"

variable = "변수는 이렇게 차후에 다른 값을 할당할 수 있지만"
constant = "상수는 차후에 값을 변경할 수 없습니다" // <---- 에러 발생 (Cannot assign to value:'constant'is a 'let' constant)

상수 선언 후에 나중에 값 할당받기
(나중에 할당하려고 하는 상수나 변수는 타입을 꼭 명시해주어야 한다.)

// 상수 선언
let sum: Int
let inputA: Int = 100
let inputB: Int = 200

// 선언 후 첫 할당
sum = inputA + inputB

변수도 마찬가지로 차후에 할당하는 것이 가능하다.

var nickName: String

// 선언 후 첫 할당
nickName = "Jamong"

// 첫 할당 이후에도 다른 값을 할당가능
nickName = "자몽"

Day 2 - 2023.01.04

기본 데이터 타입

Swift의 기본 데이터 타입은 Bool, Int, UInt, Float, Double, Character, String이 있다.
다른 언어와는 다르게 데이터타입에 엄격한 언어이다. (다른 데이터타입과 자료교환은 암시적으로 불가능하다.)

Bool.swift

// Bool 타입
var someBool: Bool = true
someBool = false

// 다른 언어에서는 0은 true 그 외의 수는 false로 받는데 Swift에서는 Int로 받아 에러가 발생한다.
// 에러 (error: cannot assign value of type 'Int' to type 'Bool"
someBool = 0
someBool = 1
Int.swift

// Int 타입 (64bit 양의 정수, 음의 정수)
var someInt: Int = -100
someInt = 100

// 실수를 넣으면 오류가 발생
// 에러 (error: cannot assign value of type 'Double' to type 'Int')
someInt = 100.1
UInt(Unsigned int).swift

// UInt 타입 (64bit 양의 정수)
var someUInt: UInt = 100

// 음수를 넣으면 오류 발생
// 에러 (error: negative integer '-100' overflows when stroed into unsigned type 'UInt')
someUInt = -100

// UInt에 Int로 선언된 변수를 넣어도 오류 발생
// 에러 (error: cannot assign value of type 'Int' to type 'UInt')
someUInt = someInt
Float.swift

// Float 타입 (실수.6)
var someFloat: Float = 3.14

// Float 타입에 (정수를 넣어도 상관없음)
someFloat = 3
Dobule.swift

// Double 타입 (실수.12)
var someDouble: Double = 3.14
someDouble = 3 

// Double에 Float로 선언된 변수를 넣어도 오류 발생
// 에러 (error: cannot assign value of type 'Float' to type 'Double')
someDouble = someFloat
Character.swift

// Character 타입 (문자 하나: 유니코드)
var someCharacter: character = ”⚾️"
someCharacter = "☺️"
someCharacter = "가"
someCharacter = "A"

// 문자열을 입력하면 오류 발생
// 에러 (error: cannot assign value of type 'String' to type 'Character')
someCharacter = "자몽"
String.swift

// String 타입 (문자열: 유니코드)
var someString: String = "자몽 ⚾️"
// 문자열 덧셈 가능 (이어붙이기)
someString = "I Love" + someString

// String에 Character로 선언된 변수를 넣어도 오류 발생
// 에러 (error: cannot assign value of type 'Character' to type 'String')
someString = someCharacter

Any, AnyObject, nil

Any는 Swift의 모든 타입을 지칭하는 키워드 (데이터 타입에 입력 가능)

AnyObject는 모든 클래스 타입을 지칭하는 프로토콜

nil은 없음을 의미하는 키워드 (NULL, Null, null 등과 유사한 표현)

Type Any.swift

// Any 타입 (어떤 타입도 수용 가능함)
var someAny: Any = 100
someAny = "문자열 가능"
someAny = "17321.3"

// Double(다른 타입도 마찬가지)에 Any으로 선언된 변수를 넣어도 오류 발생
// 에러 (error: cannot convert value of type 'Any' to specified type 'Double'
let someDouble: Double = someAny
AnyObject.swift

// 클래스 오브젝트 생성
class SomeClass {}

// AnyObject로 클래스를 변수에 넣어줄 수 있다.
var someAnyObject: AnyObject = someClass()
nil.swift

// Any타입은 nil을 넣을 수 없어 오류 발생
someAny = nil
someAnyObject = nil

컬렉션 타입(Array, Dictionary, Set)

Swift에는 여러 값 묶을 수 있는 Array, Dictionary, Set이 있다.

Array는 순서가 있는 리스트 컬렉션

Dictionary는 keyvalue의 쌍으로 이루어진 컬렉션

Set은 순서가 없고 멤버가 유일한 컬렉션

Array.swift

// 빈 Array 생성
var integers: Array<Int> = Array<Int>()

// Array 생성 축약 방법
var doubles: Array<Double> = [Double]()
var Strings: [String] = [String]()
var characters: [Character] = []

// let을 사용하여 Array를 선언하면 불변 Array (변경 불가능)
let immutableArray = [1, 2, 3]

// Array 추가
integers.append(1)
integers.append(100)

// 데이터 타입이 다른 값을 넣으면 오류 
integers.append(101.1)

// Array에 데이터가 있는지 확인하기 (contains)
integers.contains(100)			// true
integers.contains(99)			// false

// Array에 데이터 삭제
integers.remove(at: 0)			// 0번째 Array 값 삭제
integers.removeLast()			// 마지막번째 Array 값 삭제
integers.removeAll()			// Array에 모든 값 삭제

// Array 값 갯수 확인
integers.count
Dictionary.swift

// Key가 String타입, Valuer가 Any타입인 빈 Dictionary 생성
var anyDictionary: Dictionary<String, Any> = [String: Any]()

// Dictionary 축약 생성 방법
var emptyDictionary: [String: String] = [:]

// let을 사용하여 Dictionary를 선언하면 불변 Dictionary (변경 불가능)
var initalizedDictionary: [String: String] = ["name": "Jamong", "gender": "male"]

// Dictionary 값 할당
anyDictionary["someKey"] = "value"
anyDictionary["anotherKey"] = 100

// Dictonary 값 확인
anyDictionary 					// ["someKey": "value", "anotherKey": 100]

// Dictonary 키에 대한 값을 변경 가능
anyDictionary["someKey"] = "dictionary"

// Doctonary 키 삭제 (removeValue 또는 nil)
anyDictionary.removeValue(forKey: "anotherKey")
anyDictionary["someKey"] = nil
Set.swift

// 빈 Set 생성
var integerSet: Set<Int> = Set<Int> ()

// Set 값 할당 (insert)
integerSet.insert(1)
integerSet.insert(100)
integerSet.insert(99)

// Set 값 중복으로 추가 안됌
integerSet.insert(99)
integerSet.insert(99)

// Set에 데이터가 있는지 확인하기 (contains)
integerSet.contains(1)			// true
integerSet.contains(2)			// false

// Set에 데이터 값 삭제하기 (remove)
integerSet.remove(100)			// 100이라는 값 삭제
integerSet.removeFirst()		// 처음값 삭제

// Set 데이터 갯수 확인 (count)
integerSet.count

// setA 와 setB 예제 생성
let setA: Set<Int> = [1, 2, 3, 4, 5]
let setB: Set<Int> = [3, 4, 5, 6, 7]

// Set 데이터 합치기 (union)
let union: Set<Int> = setA.union(setB)			// {2, 4, 5, 6, 7, 3, 1}

// 정렬하기(sorted)
let sortedUnion: [Int] = union.sorted()			// {1, 2, 3, 4, 5, 6, 7}

// 교집합 (intersection)
let intersection: Set<Int> = setA.intersection(setB) // {5, 3, 4}

// 차집합 (subtracting)
let subracting: Set<Int> = setA.subtracting(setB)	// {2, 1}

Day 3 - 2023.01.05

함수 기본

Function.swift

// 함수의 선언
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 ...) -> 반환타입 { 
	함수 코드(구현)
    return 반환값
}

// 예제 (firstNum과 secondNum이 Int 타입의 매개변수를 가지며 Int 타입의 값을 반환하는 함수)
func sum(firstNum: Int, secondNum: Int) -> Int {
	return firstNum + secondNum
}

// 반환 값이 없는 함수 (Void)
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름, 매개변수2타입 ...) -> Void {
	함수 코드(구현)
    return
}

// 예제 (Void)
func printMyName(name: String) -> Void {
	print(name)
}

// 반환 값이 없는 경우, 반환 타입(Void)을 생략해 줄 수 있다.
func printYourName(name: String) {
	print(name)
}

// 매개변수가 없는 함수 ()
func 함수이름() -> 반환타입 {
	함수 코드(구현)
    return 반환값
}

// 예제 ()
func maximumIntegerValue() -> Int {
	return Int.max
}

// 매개변수와 반환값이 없는 함수 () -> Void
func 함수이름() -> Void {
	함수 코드(구현)
    return
}

// 예제 () -> Void
func hello() -> Void {
	print("hello")
}


// 함수의 호출
sum(firstNum: 3, secondNum: 5)			// 8
printMyName(name: "Jamong")				// Jamong
printYourName(name: "dodo")				// dodo
maximumIntegerValue()					// Int의 최댓값
hello()									// hello

함수의 고급

Funtion_advanced.swift

// 매개변수 기본값 (기본값을 갖는 매개변수는 매개변수 목록 중에 뒤쪽에 위치하는 것이 좋다.)
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 = 매개변수 기본값...) -> 반환타입 {
	함수 코드(구현)
    return 반환 값
}

// 예제 (매개변수 기본값)
func greeting(friend: String, me: String = " Jamong") {
	print("Hello \(friend)! I'm \(me)")

// 매개변수 기본값을 가지는 매개변수는 생략할 수 있다.
greeting(friend: "dodo")

// 전달인자 레이블 (함수를 호출할 때, 매개변수의 역활을 좀 더 명확하게 하거나 함수 사용자의 입장에서 표현하고자 할 때 사용한다.)
func 함수이름(전달인자_레이블 매개변수1이름: 매개변수1타입, 전달인자_레이블 매개변수2이름 : 매개변수2타입 ...) -> 반환타입 {
	함수 코드(구현)
   	return
}

// 예제 (전달인자 레이블)
func greeting(to friend: String, from me: String) {
	print("Hello \(friend)! I'm \(me)")
}

// 함수를 호출할 때에는 전달인자 레이블을 사용해야 한다.
greeting(to: "dodo", from: "Jamong")


// 가변 매개변수 (전달 받을 값의 개수를 알기 어려울 때 사용할 수 있다.)
// 가변 매개변수는 함수당 하나만 가질 수 있다.
func 함수이름(매개변수1이름: 매개변수1타입, 전달인자_레이블 매개변수2이름: 매개변수2타입...) -> 반환타입 {
	함수 코드(구현)
    return
}

// 예제 (가변 매개변수)
func sayHelloToFriends(me: String, friends: String...) -> String {
	return "Hello \(friends)! I'm \(me)!"
}

print(sayHelloToFriends(me: "Jamong", friends: "dodo", "kevin", "hana"))	// Hello ["dodo", "kevin", "hana"]! I'm Jamong!

print(sayHelloToFriends(me: "Jamong"))	// Hello []! I'm Jamong


/*
 "데이터 타입으로서의 함수"
 
 위에 설명한 함수의 다양한 모양은 모두 섞어서 사용 가능하다.

 Swift는 함수형 프로그래밍 패러타임을 포함하는 다중 패러다임 언어이다.
 Swift의 함수는 일급객체이므로 변수, 상수 등에 저장이 가능하고 매개변수를 통해 전달할 수 도 있다.
*/

// 함수의 타입표현 (반환타입을 생략할 수 없다.)
// (매개변수1타입, 매개변수2타입 ...) -> 반환타입

// 변수에 함수를 넣어줄 수 있다. (타입이 다른 함수는 할당 할 수 없음)
var someFunction: (String, String) -> Void = greeting(to:from:)

someFunction = greeting(friend:me:)

조건문(if-else, switch)

Swift 조건문은 크게 if_else구문과 switch구문으로 살펴볼 수 있다.

if-else.swift


// if-else 구조 (condition에는 항상 Bool 타입이 들어와야 한다.)
if condition(Bool타입) {
	statements
} else if condition(Bool타입) {
	statements
} else {
	statements
}

// 예제
if someInteger < 100 {
	print("100 미만")
} else if someInteger > 100 {
	print("100 초과")
} else {
	print("100")
}
switch.swift

// switch 구조 (default 구문을 꼭 작성해야한다.)
switch value {
case pattern:
	code
default:
	code
}

// 예제(범위 연산자 사용: ...)
switch someInteger {
case 0:
	print("zero")
case 1..<100:
	print("1~99")
case 100:
	print("100")
case 101...Int.max:
	print("over 100")
default:
	print("unknown")
      
// 정수 외의 대부분의 기본 타입을 사용할 수 있다.
switch "Jamong" {
case "dodo":
	print("dodo")
case "kevein":
	print("kevin")
case "polaris":
	print("polaris")
case "Jamong":
	print("Jamong")
default:
	print("unknow")
    
// break문을 걸지 않아도 자동으로 break가 걸린다.
// fallthrough문을 걸어주게 되면 바로아래 case까지 간다.

Day 4 - 2023.01.06

반복문(for-in, while, repeat-while)

for-in.swift

// for-in 구문 기본 형태
for item in items {
	실행 코드(구문)
}

// 딕셔너리의 경우 이터레이션 아이템으로 튜플이 들어온다.
var integers = [1, 2, 3]
let people = ["Jamong": 10, "yagom": 15, "mike": 12]

for integers in integers {
	print(integers)
}

// name은 key, age는 value가 들어간다.
for (name, age) in people {
	print("\(name): \(age)")
}   
while.swift

// while 구문 기본 형태 (condition에는 bool값이 들어가야 한다.)
while condition {
	실행 코드(구문)
}

// 예제 
var integers = [1, 2, 3]

while integers.count > 1 {
	integers.removeLast()
}
repeat-while

// repeat-whil 구문 기본 형태 (먼저 구문 실행 후 조건 체크)
repeat {
	code
} while condition

// 예제 
var integers = [1, 2, 3]

repeat {
	integers.removeLast()
} while integers.count > 0

Day 5 - 2023.01.08

옵셔널(Optional)

옵셔널이란 값이 있을 수도, 없을 수도 있음을 표현한다.
상수에 nil을 할당하려하면 오류가 발생하는데, 옵셔널은 nil의 가능성을 명시적으로 표현해 줄 수 있다.

nil 가능성을 문서화 하지 않아도 코드만으로 충분히 표현이 가능하고, 전달받은 값이 옵셔널이 아니라면 nil 체크를 하지 않아도 안심하고 사용할 수 있어서 옵셔널이 존재한다.

열거형(enum)과 general의 합작품으로 구성을 보자면

optional.swift

enum Optional<Wrapped> : ExpressibleByNilLiteral {
	case none			// 값이 없다
    case some(Wrapped)	// 값이 있다
}

// 옵셔널 문법(?)
let optionalValue: Optional<Int> = nil
let optionalValue: Int? = nil

암시적 추출 옵셔널(Implicitly Unwrapped Optional)

옵셔널에서 느낌표(!)를 쓰는 경우

var optinalValue: Int! = 100

switch optionalValue {
	case .none:
    	print("This Optional variable is nil")
    case .some(let value):
    	print("Value is \(value)")
}

// 기존 변수처럼 사용 가능
optionalValue = optionalValue + 1

// nil 할당 가능
optionalValue = nil

// 잘못된 접근으로 인한 런타임 오류 발생 (nil값에 변수 접근)
optionalValue = optionalValue + 1

일반적인 옵셔널(?)

var optinalValue: Int? = 100

switch optionalValue {
	case .none:
    	print("This Optional variable is nil")
    case .some(let value):
    	print("Value is \(value)")
}

// nil 할당 가능
optionalValue = nil

// 기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이므로 연산불가
optionalValue = optionalValue + 1

Day 6 - 2023.01.09

옵셔널 추출

옵셔널 추출이란?
옵셔널에 들어있는 값을 사용하기 위해 꺼내오는 것으로 옵셔널 바인딩(Optional Binding)강제 추출(Force Unwrapping)dl 있다.

옵셔널 바인딩(Optional Binding)

옵셔널 바인딩은 nil 체크를 하는과 동시에 안전한 값을 추출한다.
즉, 옵셔널 안에 값이 들어있는지 확인하고 값이 있으면 값을 꺼내온다.

옵셔널 바인딩은 if-let 방식을 사용한다.

OptionalBinding.swift

func printName(_ name: String) {
	print(name)
}

var myName: String! = nil

if let name: String = myName {
	printName(name)
} else {
	print("myName == nil")
}

// 여러개의 옵셔널 바인딩도 가능
var myName: String? = "Jamong"
var yourName: String? = nil

// yourName이 nil이기 때문에 실행 안됨
if let name = myName, let friend = yourName {
	print("\name) and \(friend)")
}

yourName = "hana"

if let name = myName, let friend = yourName {
	print("\name) and \(friend)")
}
// Jamong and hana

강제 추출(Force Unwrapping)(!)

강제 추출은 옵셔널에 값이 들어있는지 아닌지 확인하지 않고 강제로 깞을 꺼내는 방식으로 만약 값이 없을경우(nil) 런타임 오류가 발생하기에 추천하지 않는 방식

ForceUnwrapping.swift

var myName: String? = Jamong
var yourName: String! = nil 

printName(myName!)	// Jamong (옵셔널 변수 뒤에 느낌표를 붙이면 강제 추출)

print(yourName!)	// 강제추출시 값이 없어 런타임 오류 발생
profile
새해 목표 : 1일 1 깃, 블로그, 프로그래머스 2문제

0개의 댓글