ちんたら勉強しているRust言語です。Exampleのソースコードを拝見していて気になるのが、selfだったり、Selfだったりする self です。Pythonのselfのような「慣用語」的お約束ではなく keyword みたいです。大文字になったり、小文字だったり、&がついたり、::がついたり一体全体これは何?
※「やっつけな日常」投稿順 indexはこちら
Rustのソースを読んでいると時々目につく self ですが、最初は「そんなもん」で通り過ぎていましたが、だんだんそうもいってられなくなりました。以下のような形で度々登場してくるためです。
-
- self
- &self
- self::
- -> Self
それにちゃんと self と書かないとエラーになります。Pythonのself のような慣用句的お約束ではありません。
今回は、何時もお世話になっております、「Rust By Example 日本語版」様の以下のページを参照させていただいております。
そんな理解でいいのか?
self:: として現れてくる self は、「同じモジュールスコープ」を明示的に示すために使われる、と。いくつかのスコープに同名の関数があるような場合に、明示的に自階層を指し示すために使えるようです。
Self として大文字で現れてくる Self は、「自オブジェクトの型」を示すためのものみたいです。トレイトであったり、ジェネリクスであったり Rust には「任意の型になりうる」データがありえ、そいつらのその時の型を指し示したいときに大文字の Self が使えると。戻り値の型として登場すれば -> Self となると。
小文字の self はメソッドが作用するオブジェクト自身を指すみたいですが、&self とか、*selfとかにもなりうるのがちょっとヤバイです。
いい加減な理解で書いたソース
実験のため、上記のいい加減な理解で書いたソースが以下に。trait とか impl とか慣れないことしています。大丈夫か?
struct Abc { dat1: i32, } trait Xyz { fn new(dat1: i32) -> Self; fn d1(&self) -> i32; } impl Xyz for Abc { fn new(dat1: i32) -> Abc { Abc { dat1: dat1 } } fn d1(&self) -> i32 { self.dat1 } } fn d1(arg: &Abc) { println!("fn d1 = {}", arg.dat1); } fn main() { println!("Self, self"); let test: Abc = Xyz::new(34); d1(&test); println!("test.d1={}", test.d1()); }
実行結果
上記を実行してみたところが以下に。
一応、大文字の Self も 小文字の self も意図通りに動いてくれているみたいだけれども何だかな~、直ぐに間違えちゃいそうだな~。