Self vs self
self키워드의 사용 (소문자)
- 인스턴스를 가르키기 위해 사용
class Person {
var name: String
init(name: String) {
self.name = name
}
}
- 값타입에서 새로운 속성으로 초기화가 가능한 패턴
struct Calculator {
var number: Int = 0
mutating func plusNumber(_ num: Int) {
number = number + num
}
mutating func reset() {
self = Calculator()
}
}
- 타입속성에서 사용하면, 인스턴스가 아니라 타입자체를 가리킨다
struct MyStruct {
static let club = "iOS부서"
static func doPrinting() {
print("소속은 \(self.club)입니다.")
}
}
- 타입 인스턴스를 가르키는 경우에 사용
- 타입인스턴스 : 메모리에 올라와있는 붕어빵 틀 자체를 가리킴
class SomeClass {
static let name = "SomeClass"
}
let myClass: SomeClass.Type = SomeClass.self
SomeClass.name
SomeClass.self.name
Self키워드의 사용 (대문자)
- (특정 타입 내부에서) 해당 타입을 가르키는 용도로 Self를 사용
- 타입을 선언하는 위치에 사용한다
- 타입속성/타입메서드를 지칭하는 자리에서 대신사용한다
extension Int {
static let zero: Self = 0
var zero: Self {
return 0
}
var zero: Int {
return 0
}
static func toZero() -> Self {
return Self.zero
}
func toZero() -> Self {
return self.zero
}
}
프로토콜에서의 Self사용 (프로토콜을 채택하는 해당 타입을 가르킴)
- 특정 타입에서 extenstion을 사용하면 모든 타입에 해당하는 return 타입을 전부다 구현해줘야하지만 Self라는 해당타입자체를 지칭하는 키워드를 사용하면 Int에서는 Int를 float에서는 float을 반환해주는 함수로 유연하게 사용이 가능하다
- 확장성이 좋아진다
extension BinaryInteger {
func squared() -> Self {
return self * self
}
}
protocol Remote {
func turnOn() -> Self
}
extenstion String: Remote {
func turnOn() -> Self {}
}