QA@IT

Scalaでメソッドを一つしか持たないtraitはJavaの関数型インタフェース的な扱いになるのでしょうか?

8455 PV

最近勉強し始めたScalaについて質問させていただきます。
たまたまですが、メソッドを一つしか持たないtraitのインスタンス化について、メソッド名を省略した実装が可能なことが確認できました。

trait Hoge {
    def fuga(s: String): String
}

def piyo(): Hoge = {
    (s: String) => s + "bbbbb"
}

println(piyo().fuga("aaaaa"))

しかし、piyoの定義の書き方は以下であるべきだと思っていたので、メソッド名とnew演算子が省略できる事がどうも腑に落ちません。

def piyo(): Hoge = new Hoge {
    def fuga(s: String): String = s + "bbbbb"
}

なお、traitはJavaのインターフェースに変換されるということなので、関数型インターフェースの振る舞いをしているのかと思いましたが、下記の呼び出し方は通じませんでした。

println(piyo("aaaaa"))

どういう理由で、このpiyoの定義の書き方が許容されるのかご存知でしたら、ご教授いただきたく思います。

回答

java 8から(lambda式のために?)導入されたSingle-Abstract-Methodによるもののようです。

public class Main {
    interface MySamIntPredicate {
        boolean predicate(int x);
    }

    public static void main(String[] args) {
        int param = 1;
        MySamIntPredicate over10 = x -> x > 10;  // これ
        System.out.println("Is " + param + "  greater than 10 ? " + over10.predicate(param));
    }
}

シンタックスシュガーですかね。

IntelliJ上で scalaファイルでもそのように変換ヒントに表示されます(というかそれで知りました)。

ss2018-07-22_22.00.06.png

__________2018-07-22_22.01.42.png

最終的にはここまで省略できます。

def piyo(): Hoge = s => s + "bbbbb"
編集 履歴 (0)

なるほど、このように書くことでラムダ式のインターフェースとして働くのですね。
理解できました!ありがとうございます。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。