본문 바로가기

[Swift 5.1] Self 키워드의 기능 추가 (SE-0068)

기술적인 이야기/애플 플랫폼 개발 2019. 10. 13.
반응형

macOS Catalina 공식 버전 출시 이후로 늦었지만 Swift 5.1의 변화점들에 대해 공부하고 있습니다. 이 글을 시작으로 Swift 5.1에서 뭐가 바뀌었는지 눈에 띄는 것들을 글로 정리해보고자 합니다.

첫 글은 SE-0068 Expanding Swift Self to class members and value types에서 소개된 Self의 기능 확장에 대한 이야기입니다.

뭐 아시겠지만 Self는 원래 자기 자신의 동적 클래스(dynamic class)를 가리키는 키워드입니다.

우선 예제를 살펴봅시다.

class MyClass {
    class var name: String {
        return "unknown name"
    }

    func show() {
        print("My name is \(MyClass.name)")
    }
}

class AnotherClass: MyClass {
    override class var name: String {
        return "another name"
    }
}

let obj = AnotherClass()
obj.show()    // "unknown name"

위 예제는 주석에도 써놨다시피 AnotherClass 타입 인스턴스의 show() 메서드는 "unknown name"을 콘솔에 표시합니다. 당연합니다. MyClass 클래스에 정의된 name 이라는 클래스 변수를 출력하게 만들어졌으니까요.

하지만 우리는 MyClass의 자식 클래스에서 show() 메소드를 그대로 사용하면서 클래스 변수인 name만을 오버라이드 하고 싶습니다. 그렇다면 어떻게 해야 할까요?

Swift 5.1에서는 이를 상속받은 클래스에서 정의하는 class 멤버(혹은 static 멤버)를 참조할 수 있도록 Self 키워드에 능력이 추가됩니다. 따라서 위의 MyClassshow() 메서드를 아래와 같이 수정할 수 있습니다.

    func show() {
        print("My name is \(Self.name)")
    }

self가 아닌 Self입니다. 첫 글자가 대문자인 것에 주의합시다.

이렇게 하면 이제 AnotherClass의 인스턴스에서 show() 메소드를 호출하면 의도대로 "another name"이 콘솔에 표시됩니다. 이런 식으로 Self 키워드를 사용할 수 있습니다.

Self는 이외에도 여러 용도로 활용됩니다. 아래처럼 상속 대신 프로토콜에 맞춰 구현한 구조체(struct)도 static 멤버 액세스를 하기 위해 Self를 사용할 수 있습니다.

protocol MyType {
    static var name: String { get }
    func show()
}

extension MyType {
    func show() {
        print("My name is \(Self.name)")
    }
}

struct John: MyType {
    static var name = "John"
}

struct Conrad: MyType {
    static var name = "Conrad"
}

let j = John()
j.show()    // "John"

let c = Conrad()
c.show()    // "Conrad"

extension을 이용해 MyType의 show() 메서드를 직접 구현한 경우 이 녀석도 실체를 구현하는 값을 참조하도록 Self 키워드를 사용한 예제입니다. 기존의 경우... 방법이 있을까요? :D

728x90
반응형

댓글