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
orimpl
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
가 속해 있는 trait
나 impl
블록에서의 타입을 의미한다는 것입니다.