[ Swift ] self 키워드와 Self 키워드

EarthSea·2023년 8월 11일
1

🚩 Swift 문법

목록 보기
1/5
post-thumbnail


스위프트 언어를 사용하면 self키워드Self 키워드를 사용할 때가 종종 있어요.
하지만, 명확하게 self 키워드와 Self 키워드의 용도를 모르고 쓸 때가 있더라구요.

두 키워드의 차이를 명확히 알고 쓰기위해서 한번 비교해봅시다!

우선 키워드들의 개념과 사용 목적에 대해서 정리할게요.




self 키워드


정의

self 키워드는 주로 인스턴스를 가르킨다.

사용 목적

  1. 인스턴스 내부에서 인스턴스의 속성을 더 명확하게 가르키기 위해 사용

    class Student {
        var name = "배지해"
        func setName(_ name: String){
            self.name = name
        }
    }


    여기서 "함수 setName의 파라미터인 name"과 "클래스 Student의 저장 속성인 name"의 변수명이 겹친다. 만약, name = name 이라고 입력하게 된다면, 컴파일러는 두 개의 name 모두를 함수 setName의 파라미터인 name으로 인식하게 될 것이다. ( 컴파일러는 가장 가까이에 있는 변수로 인식하기 때문에 )

    이런 경우에 사용자가 가르키는 name이 어떤 것인지 컴파일러에게 명확하게 표시하기 위해서 self 키워드를 사용한다.

    -> self.name = name

    self는 인스턴스를 가르키기 때문에, self.name은 "클래스 Student의 저장 속성인 name" 으로 인식할 것이고, name은 가까운 것 즉, 함수 setName의 파라미터인 name로 인식할 것이다.


  1. 구조체나 열거형에서 인스턴스 자체의 값을 치환할 때 사용

    struct Calculater {
        var number = 0
    
        mutating func reset() {
            self = Calculater()
        }
    }

    구조체나 열거형(값타입)에서 인스턴스 그 자체를 `self`라고 지칭할 수 있다.

    예를 들어, 인스턴스를 초기화시키는 reset() 이라는 함수를 구현한다고 해보자. 인스턴스 자기 자신을 Calculater()로 정의해야한다. 이럴때 self 키워드를 사용할 수 있다.

    -> self = Calculater()


mutating 키워드 : 구조체나 열거형에서 자기 자신의 속성을 변경하는 경우에 사용하는 키워드이다.


  1. 타입속성 / 메서드에서는 타입 자체를 가르킴.

    struct A {
        static var a = 0
        static func printing() {
            print("a는 \(self.a)입니다.")
        }
    }
    

    타입 속성이나 타입 메서드에서 self 키워드는 타입 자체를 의미한다.

    위의 예제를 보면, A 라는 구조체에 타입 저장 속성 a 와 타입 메서드 printing() 이 존재한다. 이때, printing() 이라는 함수에서 타입 저장 속성 a 를 불러오고 싶을 때 self.a 를 사용한다.

    어떻게 보면 1의 설명인 인스턴스를 가리키는 설명과 동일하다고 생각할 수 있는데, 아래의 예제를 보자.

    struct A {
        static var a = 0
        func printing() {
            print("a는 \(A.a)입니다.")
        }
    }

    위의 코드와 다른점은 self.a 가 아닌 A.a 라고 표현한 부분이다.

    printing() 이라는 함수를 구조체가 아닌 인스턴스 메서드로 선언한 경우엔 self.a 라고 표현한다면 에러가 뜬다. a는 구조체의 타입 저장 속성이기 때문에 A의 인스턴스 에서 static 저장 속성 a 에 접근할 수 없기 때문이다. 즉, 타입 자체에서 static 변수에 접근을 해야하기 때문에 A.a로 써야한다.


  1. 외부에서 인스턴스 타입에 접근할 때 사용

    class Someclass {
        static var something = 0
    }
    
    let myclass: Someclass.Type = Someclass.self

    타입 인스턴스를 가리키는 경우에 Someclass.self 를 사용한다.

    Someclass.Type은 아직 배우지 않은 메타타입개념이다.

타입 인스턴스 : 클래스/구조체/열거형에서 static을 붙여 선언한 타입 속성이나 타입 메서드들이 데이터 영역에 존재하는 그 자체를 타입 인스턴스라고 한다.




Self 키워드


정의

Self 키워드는 주로 타입을 가르킨다.
이 때, 타입은 특정한 타입이 아닌, 특정 타입의 내부에서 해당 타입을 가르킨다.

사용 목적

  1. 특정 타입 내부에서 타입을 선언하는 위치에 사용

  2. 특정 타입 내부에서 타입속성 / 타입메서드를 지칭하는 위치에서 타입 대신 사용

    extension Int {
    
        // 인스턴스 계산 저장 속성
        var zero: Self {
            return 0
        }
    
        // 타입 저장 속성
        static var zero: Self = 0
    
        // 인스턴스 메서드
        func toZero() -> Self {
            return self.zero
        }
    
        // 타입 메서드
        static func toZero() -> Self {
            return Self.zero
        }
    }

    -> var a: Int

    변수 a의 타입을 Int로 선언하는 코드이다.

    위의 예제처럼 Int 라는 타입의 구조체를 확장한다고 했을 때, 변수의 타입 선언에서 Int 타입을 Self 키워드로 사용할 수 있다.

    위의 예제의 타입 메서드 toZero()를 보면 타입속성을 지칭하는 위치에서 Int.zeroSelf.zero 로 대신 사용할 수 있다.


  1. 프로토콜에서 채택하려는 타입을 지칭가능

    protocol remote {
        func turnOn() -> Self
    }
    
    // 스트링 타입을 확장하면서 remote 프로토콜을 채택
    extension String: remote {
        func turnOn() -> String {
            return "tv를 켜다"
        }
    }
    

    프로토콜에서 함수 turnOn()의 리턴 타입에 Self 키워드를 넣으면, 해당 remote 프로토콜을 채택하는 함수가 turnOn() 이라는 함수를 선언할 때, 채택하는 함수의 타입이 자동적으로 입력이 된다.


두 키워드의 차이를 아시겠나요?

정리를 해보자면,

self VS Self

구분selfSelf
의미인스턴스타입

전체적으로 큰 차이는 인스턴스를 가르키는 것과 타입을 가르키는 것을 알 수 있습니다.

profile
I'm Junior iOS developer 배지해.

0개의 댓글