self와 Self

이 포스트는 Rust를 처음 공부하면서 정리한 내용입니다. 해당 포스트는 개인적으로 기억하기 위한 메모 성격에 가깝습니다. “러스트 프로그래밍 공식 가이드 (2018, 제이펍)” 서적을 참고하였으며, 러스트 공식 사이트 에서 책과 동일한 내용을 찾을 수 있습니다. 따라서 더 자세한 내용을 찾으시면 위의 링크를 참고하시면 좋습니다.

이전 포스트에서 다루었던 예제 중 Self 키워드가 등장하는 코드가 있습니다. 이에 대해 공식 문서 조금 더 자세히 알아보겠습니다.

이와 관련되어 있는 좋은 글이 있어 스택오버플로우도 참고하였습니다.

self

self는 두 가지의 쓰임이 있습니다. 이전에 모듈을 공부할 때 보았던 경로(path)를 지정하는 경우와 함수의 인자로 사용되어 메서드임을 의미하는 경우입니다. 여기에서는 경로로 사용되는 self의 경우는 제외하겠습니다.

조금 더 자세히 살펴보겠습니다. self문서에서 아래와 같이 설명되어 있습니다.

self as the current receiver for a method … (생략)

self는 메서드를 정의할 때 첫 번째 인자로 사용되어 연관 함수와 구분되는 차이점이었습니다. self를 매개변수로 가지고 가는 함수는 . 연산자로 인스턴스에서 직접 호출이 가능했었습니다.

SelfTy

공식 문서에는 대문자로 시작하는 Self의 경우 SelfTy으로 나와 있습니다. 기에서 Self는 아래와 같이 설명되어 있습니다.

The implementing type within a trait or impl block, or the current type within a type definition.

즉, 현재 정의되어 있는 타입으로 정의합니다.

// 구조체 정의에서의 Self
struct Node {
    elem: i32,
    // `Self` is a `Node` here.
    next: Option<Box<Self>>,
}

// Impl 블록에서의 Self
struct Foo(i32);

impl Foo {
    fn new() -> Self {
        Self(0)
    }
}

struct Wrap<T> {
    elem: T,
}

impl<T> Wrap<T> {
    fn new(elem: T) -> Self {
        Self { elem }
    }
}

// Trait 블록에서의 Self
trait Example {
    fn example() -> Self;
}

struct Foo(i32);

impl Example for Foo {
    fn example() -> Self {
        Self(42)
    }
}

물론 아래와 같이 명시적으로 타입을 지정해도 무관합니다.

impl Clone for MyType {
    // I can use either the concrete type (known here)
    fn clone(&self) -> MyType;

    // Or I can use Self again, it's shorter after all!
    fn clone(&self) -> Self;
}

이때 주의할 점은 Self는 현재 Self가 속해 있는 traitimpl 블록에서의 타입을 의미한다는 것입니다.

태그:

카테고리:

업데이트: