없어도 될거 같은 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 해야함
이것도 코드 일반화와 융통성 있게 만들어 주는 것과 일맥 상통! 정리 끝__