[Swift] self vs Self
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)입니다.")
}
// 타입 자체를 가르키기 때문에 외부에서 접근하려면 타입으로 접근 해야함
// func doPrinting() {
// print("소속은 \(MyStruct.club)입니다.")
// }
}
- 외부에서 타입을 가르킬 때 타입 인스턴스를 가르키는 경우에 사용
class SomeClass {
static let name = "SomeClass"
}
// 메타 타입
let myClass: SomeClass.Type = SomeClass.self
Self 키워드
- 특정 타입 내부에서 해당 타입을 가르키는 용도로
Self
를 사용
// 1) 타입을 선언하는 위치에서 사용하거나,
// 2) 타입속성/타입메서드를 지칭하는 자리에서 대신 사용 가능
extension Int {
// 타입 저장 속성
static let zero: Self = 0 // Int 타입
//static let zero: Int = 0
// 인스턴스 계산속성
var zero: Self { // 1) 타입을 선언하는 위치에서 사용
return 0
}
// var zero: Int {
// return 0
// }
// 2) 타입 속성/메서드에서 지칭
static func toZero() -> Self {
return Self.zero // Int.zero
}
// 인스턴스 메서드
func toZero() -> Self {
return self.zero // 5.zero
}
}
- 프로토콜을 채택하는 해당 타입을 가르키는 경우
// 프로토콜의 확장 -> 구현의 반복을 줄이기 위한 문법
// 이진법으로 표현된 정수에서 쓰이는 프로토콜
// Int가 BinaryInteger 프로토콜을 채택
extension BinaryInteger {
func squared() -> Self { // Self : 타입자체(Int)를 가르킴
return self * self // self : 인스턴스(7)를 가르킴
}
}
// 간단하게 얘기하면 Int, UInt 간에도 비교가능하도록 만드는 프로토콜 (타입이 다름에도 비교가 가능)
let x1: Int = -7
let y1: UInt = 7
if x1 <= y1 {
print("\(x1)가 \(y1)보다 작거나 같다.")
} else {
print("\(x1)가 \(y1)보다 크다.")
}
self vs Self
구분 | self (소문자 s) | Self (대문자 s) |
---|---|---|
의미 | 인스턴스를 가르킴 | 타입을 가르킴 |
설명 | 모든 인스턴스들이 암시적으로 생성하는 속성 | Self가 특정한 타입을 가르키는 것은 아니고, 특정 타입 내부에서 사용하여 해당 타입을 가르킴 |
가르키는 대상 예시 | “hello”, 7 등의 생성된 인스턴스 | String, Int 등의 타입 |
사용 목적과 예시 | 1. 인스턴스 내부에서 인스턴스의 속성을 더 명확하게 가르키기 위해 사용 2. 값타입(구조체, 열거형)에서 인스턴스 자체의 값을 치환할 때 사용 가능 3. 타입 속성/메서드에서 사용하면, 타입자체를 가르킴 4. 외부에서 타입 인스턴스를 가르킬 때, 타입 자체의 뒤에 붙여서 사용 | 1. 특정 타입 내부에서 타입을 선언하는 위치에 사용 2. 특정 타입 내부에서 타입 속성/타입 메서드를 지칭하는 위치에서 타입 대신 사용 3. 프로토콜에서 채택하려는 타입을 지칭가능 |