Any
타입을 사용하면 여러 타입을 담을 수 있는 배열을 만들 수 있음 var all: [Any] = ["string", 1, -138923.1293, true]
enum
의 이름을 생략하고 .caseName
의 형태로 각 케이스를 호출할 수 있음enum WeatherType {
case sun, cloud, wind, rain
}
func getHaterStatus(weather: WeatherType) -> String? {
switch weather {
case .sun: // 타입 추론이 가능하므로 생략해서 표기
return nil
case .cloud, .wind:
return "dislike"
case .rain:
return "hate"
}
}
let-where 구문
을 이용해서 조건문을 추가로 만들 수 있음enum WeatherType {
case sun
case cloud
case rain
case wind(speed: Int)
case snow
}
func getHaterStatus(weather: WeatherType) -> String? {
switch weather {
case .sun:
return nil
case .wind(let speed) where speed < 10:
return "meh"
case .cloud, .wind:
return "dislike"
case .rain, .snow:
return "hate"
}
}
print(getHaterStatus(weather: .wind(speed: 5))!) // meh
print(getHaterStatus(weather: .wind(speed: 20))!) // dislike
@objc
로 표기해줘야 함@objcMembers
라고 표기해주면 됨super.init()
사용willSet
은 프로퍼티가 바뀌기 전에 호출되며 newValue
값에 바뀔 값 저장 didSet
은 프로퍼티가 바뀌고 난 뒤에 호출되며 oldValue
값에 이전 값 저장struct Person {
car clothes: String {
willSet {
updateUI(msg: "I'm changing from \(clothes) to \(newValue)")
}
didSet {
updateUI(msg: "I just changed from \(oldValue) to \(newValue)")
}
}
}
func updateUI(msg: String) {
print(msg)
}
var sun = Person(clothes: "t-shirts")
sun.clohtes = "jeans"
{ }
안에 get
혹은 set
을 이용해서 연산 프로퍼티를 만들 수 있음struct Person {
var age: Int
var ageInDogYears: Int {
get {
return age * 7
}
}
}
var fan = Person(age: 25)
print(fan.ageInDogYears) // 175
get
을 생략하고 다음과 같이 쓸 수 있음var ageInDogYears: Int {
return age * 7
}
static
키워드를 붙이면 인스턴스가 아닌 타입 자체
의 프로퍼티/메서드가 됨public
: 모두 접근 가능internal
: 해당 스위프트 코드 전체에서 접근 가능file private
: 동일한 파일에 있는 스위프트 코드에서만 접근 가능private
: 해당 타입 혹은 익스텐션에 포함되는 메서드에서만 접근 가능 class Album {
var name: String
init(name: String) {
self.name = name
}
func getPerformance() -> String {
return "The album \(name) sold lots"
}
}
class StudioAlbum: Album { // 상속
var studio: String
init(name: String, studio: String) {
self.studio = studio
super.init(name: name)
}
override func getPerformance() -> String {
return "The studio album \(name) sold lots"
}
}
class LiveAlbum: Album { // 상속
var location: String
init(name: String, location: String) {
self.location = location
super.init(name: name)
}
override func getPerformance() -> String {
return "The live album \(name) sold lots"
}
}
var taylorSwift = StudioAlbum(name: "Taylor Swift", studio: "The Castles Studios")
var fearless = StudioAlbum(name: "Speak Now", studio: "Aimeeland Studio")
var iTunesLive = LiveAlbum(name: "iTunes Live from SoHo", location: "New York")
var allAlbums: [Album] = [taylorSwift, fearless, iTunesLive]
for album in allAlbums {
print(album.getPerformance()) // 다형성에 의해 오버라이딩된 함수 호출
}
오브젝트의 실제 타입
이 바뀌는 것이 아니라 스위프트가 생각하는 해당 오브젝트의 타입
이 바뀌는 것!
옵셔널 다운캐스팅
연산자로 다운캐스팅 성공 시 옵셔널
, 실패 시 nil
반환 for album in allAlbums {
print(album.getPerformance())
if let studioAlbum = album as? StudioAlbum {
print(studioAlbum.studio)
} else if let liveAlbum = album as? LiveAlbum {
print(liveAlbum.location)
}
}
nil
이 존재하는 경우를 대비해 nil coalescing 필요!for album in allAlbums as? [LiveAlbum] ?? [LiveAlbum]() { // 다운캐스팅 실패 시 빈 배열 반환
print(album.location)
}
강제 다운캐스팅
으로 타입캐스팅 실패 시 에러 발생for album in allAlbums {
let studioAlbum = album as! StudioAlbum
print(studioAlbum.studio)
}
let number = 5
let str = String(number)
print(str) // "5"
enum
이 지금까지 다른 언어들과 달라서 좀 헷갈렸는데 나만의 타입
을 만드는 거라고 생각하니까 조금 감이 오는 것 같기도..하고...아닌 것 같기도...