드디어 기본 문법 마무리 하는 날! 두구두구두구🥁
더이상 세미콜론으로 싸우지 말자🤭
타입캐스팅: 인스턴스의 타입을 확인하거나 어떠한 클래스의 인스턴스를 해당 클래스 계층 구조의 슈퍼 클래스나 서브 클래스로 취급하는 방법
- 타입 캐스팅 연산자 is, as
class MediaItem {
var name: String
init (name: String) {
self.name = name
}
}
// MediaItem class 상속
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
// MediaItem class 상속
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
super.init(name: name)
}
}
let library = [
Movie(name: "Parasite" , director: "봉준호"),
Song(name: "Butter", director: "BTS"),
Movie(name: "Old Boy", director: "박찬욱" ),
Song(name: Wonderwall, director: "Oasis"),
Song(name: "Rain", director: "이적" ),
]
var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
movieCount += 1
} else if item is Song {
songCount += 1
}
}
print("Media library contains \(movieCount) movies and \(songCount) songs") // Media library contains 2 movies and 3 songs
// 다운 캐스팅
for item in library {
if let movie = item as? Movie {
print("Movie: \(movie.name), dir. \(movie.director)")
} else if let song = item as? Song {
print("Song: \(song.name), by \(song.artist)")
}
}
*/
Movie: Parasite, dir. 봉준호
Song: Butter, by BTS
Movie: Old Boy, dir. 박찬욱
Song: Wonderwall, by Oasis
SOng: Rain, by 이적
/*
assert와 guard
1. assert
- 특정 조건을 체크하고, 조건이 충족되지 않으면 메세지를 출력하게 하는 함수
- 디버깅 모드에서만 동작하고 주로 디버깅 중 조건의 검증을 위해 사용
2. guard
- 뭔가를 검사해 그 다음에 오는 코드를 실행할지 말지 결정함
- 설정한 조건문이 거짓일 때 구문이 실행됨
// assert
var value = 0
assert(value == 0)
value = 2
assert(value == 0, "Value is not zero") // throw error
// guard
guard 조건 else {
조건이 false면 else 구문이 실행되고
return or throw or break를 통해 이후 코드를 실행하지 않도록 한다.
}
func guardTest(value: Int) {
guard value == 0 else { return }
print("Hello")
}
guardTest(value: 2) // nothing happens
guardTest(value: 20) // Hello
어떻게 활용할 지 아직 감이 오지 않는다.. 필요할 때 다시 복습하기로
프로토콜: 특정 역할을 하기 위한 메서드, 프로퍼티, 기타 요구사항 등의 청사진
protocol 이름 {
}
protocol SomeProtocol {
}
protocol SomeProtocol2 {
}
// 프로토콜 채택
struct SomeStructure: SomeProtocol {
}
// 복수의 프로토콜 동시에 채택
struct SomeStructure2: SomeProtocol, SomeProtocol2 {
}
// class에 프로토콜을 채택
// 상속받을 superclass를 제일 먼저 써준다
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
}
// 프로토콜 채택시 요구사항 추가
protocol FirstProtocol {
// 상수(let)가 아니라 변수(var)로 요구해야 한다.
var name: Int { get set } // 읽기, 쓰기 둘다 가능
var age: Int { get } // 읽기만 가능
}
// 타입 프로퍼티 요구하려면 static 써야함
protocol AnotherProtocol {
static var someTypeProperty: Int { get set }
}
protocol FullyNamed {
var fullName: String { get set }
func printFullName()
}
struct Person: FullyNamed {
var fullName: String // 프로토콜 준수
func printFullName() {
print(fullName) // 구현하고자 하는 메서드 정의
}
}
// 프로토콜 채택시 생성자 요구사항 추가
protocol SomeProtocol4 {
init()
}
class SomeClass: SomeProtocol4 {
required init() { // required 식별자 써야함
} // 구조체에서는 required 필요없으나, class에서는 필요함
// 단 이 class가 상속받을 수 없는 final class라면 안써도 됨
}
protocol SomeProtocol3 {
func someTypeMethod() // 매개변수는 정의
}
익스텐션: Swift의 강력한 기능 중 하나, 기존의 클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가할 수 있음
// 기본 사용법
extension SomeType {
// 추가할 기능들
}
// 타입에 연산 프로퍼티 추가 (저장 프로퍼티는 추가 불가)
extension Int {
var isEven: Bool { // 짝수인지 판단
return self % 2 == 0
}
var isOdd: Bool { // 홀수인지 판단
return self % 2 == 1
}
}
var number = 3
print(number.isEven) // false
print(number.isOdd) // true
// 타입에 메서드 추가
extension String {
func convertToInt() -> Int? { // Int 타입으로 변경하는 메서드
return Int(self)
}
}
var string = "0"
string.converToInt() // 0
단, 기존의 기능에 override는 불가능
열거형: 연관성이 있는 값들을 모아 놓은 것
enum CompassPoint {
case north
case south
case east
case west
// 또는
case north, south, east, west // 도 가능
}
var dicrection = CompassPoint.east // 열거형 변수
print(direction) // east
direction = .west // 컴파일러가 이미 열거형 타입이라는 것을 추론해 내부이름 항목만으로도 사용가능
print(direction) // west
// 열거형은 switch 구문과 찰떡!
switch direction {
case .north:
print("north")
case .south:
print("south")
case .east:
print("east")
case .west:
print("west")
}
// west
// 원시값 (raw value) 설정 하는 법
enum CompassPoint: String {
case north = "북"
case south = "남"
case east = "동"
case west = "서"
}
옵셔널 체이닝: 옵셔널에 속해 있는 nil 일지도 모르는 프로퍼티, 메서드, 서브스크립션 등을 가져오거나 호출할 때 사용하는 일련의 과정
struct Developer {
let name: String
}
struct Company {
let name: String
var developer: Developer?
}
var developer = Developer(name: "Sophie")
var company = Company(name: "Gil", developer: developer)
print(company.developer?.name) // Optional(name: "Sophie")
print(company.developer!.name) // Sophie
오늘 아주 쬐끔 지루해질 뻔했지만 정적언어 문법은 생각보다 많이 흥미로웠고, 변수들을 구속하는 맛(?)이 아주 쏠쏠했다.
앞으로 기본적인 앱들을 구현해 내보면서 약 3.5일 동안 가볍게 익힌 Swift에 익숙해지도록 노력해볼 예정이다.
그리고 아직 100% 이해하지 못했거나 놓쳤거나 어떻게 쓰이는지 제대로 감이 안오는 것들은 추후에 실제로 써보면서 다시 한번 복습해야겠다.
'그냥 개인공부' 카테고리의 다른 글
Swift 기본문법 3 (2) | 2022.01.07 |
---|---|
Swift 기본문법 2 (4) | 2022.01.06 |
Swift 기본문법 1 (5) | 2022.01.05 |