Swift Self Type

없어도 될거 같은 Self 타입, 인스턴스를 가리키는 프로퍼티 self 도 아니고 메타타입 값을 나타내는 .self 도 아님.
서로 연관성 조차도 없음, 모두 다 self라서 헛갈리는데 그냥 다 다른것이라고 생각하면 됨.
The Swift Programming Language 책에 정의된 내용이다.

간단히 요약하면 구조체, 클래스, Enum 타입을 간단히 대체하기 위함, 이름을 몰라도 사용할 수 있음
이름이 Class 인 클래스가 있으면 클래스 내부에서 Class 를 Self 로 대체 가능하다.
Self 를 사용할 수 있는 곳은 위에서 표시된 4곳에서만 사용 가능하다.

class Class {
    static var typeProperty = "type property"
    var instanceProperty = "instance property"
    
    // 함수 리턴 타입으로 사용됨 f1, f2는 완전히 같음    
    func f1() -> Self { return self }
    func f2() -> Class { return self }

    // 메소드 내에서 사용됨, Class.typeProperty와 완전히 같음
    func f3() { print("\(Self.typeProperty)") }
    
    // 프로퍼티 타입으로 사용됨
    var computed1: Self {
        self.instanceProperty = "computed 1"
        return self
    }
    var computed2: Class {
        let c = Class()
        c.instanceProperty = "computed 2"
        return c
    }
}

구조체, 클래스, Enum 내부에서 “자신의 타입”으로 사용할 수 있는 곳에서 타입 대신 Self 로 대체 가능함
즉 그냥 이름 대신 편하게 사용 가능함
Self 는 뭔가를 나타내는게 아니고 그냥 단순히 타입 이름을 대신해서 쓸 수 있는 것임
그럼 “타입” 대신 왜 Self 를 사용할까? 다른 이유는 없을까?
내가 생각한 첫번째 이유는 코드의 일반화라고 생각하면 될거 같다.

func f1() -> Self { return self }
func f2() -> Class { return self }

위 2개의 클래스 메소드를 보면…
f1 메소드는 타입에 종속되지 않은 모습이고 f2 메소드는 타입에 종속된 모습니다.
f1 메소드 코드는 복사하여 다른 클래스에서 바로 사용 가능하지만
f2 메소드는 “Class”라는 타입을 명시한 곳 때문에 바로 사용할 수 없다.
좀 더 코드를 일반화, 융통성 있게 만들 수 있게 하는것 같음!

두번째 이유가 사실 중요한데… 런타임시 dynamic 타입을 명시하기 위함이다.

class Superclass {
    func typeName() -> String { return String(describing: Self.self) }
}

class Subclass: Superclass { }

let superc = Superclass()
print(superc.typeName())           // Superclass
        
let subc = Subclass()
print(subc.typeName())             // Subclass

위 처럼 타입 이름을 리턴하는 메소드의 경우 Self 를 사용하지 않고 Self 자리에 “Superclass”를 사용했다면
Subclass에서 일일히 typeName() 메소드를 override 해야함
이것도 코드 일반화와 융통성 있게 만들어 주는 것과 일맥 상통! 정리 끝__

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다