クラスベースの言語から来た身としては、変に悩んでしまったのでメモとして残しておきます。

やりたいこと:Java での実装例

タイトルだけでは何がしたいのかさっぱりわからないと思うので、実現したいことを Java で書くと以下のような感じです:

import java.util.*;

interface Service {
    int ID = 123;
    void displayId();
}

class Module implements Service {
    public void displayId() {
        System.out.println(getId());
    }

    private int getId() {
        return this.ID;
    }
}

public class Main {
    public static void main(String[] args) {
        Module module = new Module();
        module.displayId();
    }
}

要は、

    • インタフェース(Rust ではトレイト)で public なメソッドを1つ列挙しておきたい

 

    実装クラス(Rust では impl)の中で、 private なメソッドを定義して利用したい

の2点です。

Rust で実現:失敗例

これを Rust で実現しようとこのように書くとコンパイルエラーが出て怒られます:

trait Service {
    fn display(&self);
}

struct Module {
    id: u64,
}

impl Service for Module {
    fn display(&self) {
        print!("{}", get_id());
    }

    fn get_id(&self) -> u64 {
        self.id
    }
}

fn main() {
    let module = Module{
        id: 12,
    };
    module.display();
}

※Rust Playground 上での実装例

エラーメッセージは、error[E0407]: method get_id is not a member of trait Service と error[E0425]: cannot find function get_id in this scope というものです。 get_id というメソッドは Service トレイトで列挙していないので、書けないよ と怒られてしまいます。

Rust で実現:成功例

ということで、以下のようにするとコンパイラに怒られずに済みます:

trait Service {
    fn display(&self);
}

struct Module {
    id: u64,
}

impl Service for Module {
    fn display(&self) {
        print!("{}", self.get_id());
    }
}

impl Module {
    fn get_id(&self) -> u64 {
        self.id
    }
}

fn main() {
    let module = Module{
        id: 12,
    };
    module.display();
}

※Rust Playground での実装例

直したのは、 Service トレイトの実装 Module をトレイトの実装部分( impl Service for Module の箇所)と Module 独自のメソッドを定義する部分( impl Module の箇所)に分けて書く、という点です。

こうすれば、最初に Java の例で挙げたのと同じ動作が実現できます。

謝辞

この問題の解決にあたっては、rust-jp.rs の 日本語コミュニティ(Slack)の方々にお世話になりました。初心者の私の質問に迅速に丁寧にご回答いただき、非常に助かりました。

bannerAds