2016-12-16 8 views
1

のは、ScalaのREPLのコードを見てみましょう: は最初、私は形質を定義した: 匿名関数はどのようにその特性を実装しましたか?

trait Service{ 
    def invoke(name:String):String 
} 

はその後、私は匿名関数を定義した:それは正常に動作します

def serviceImpl:Service = (name)=> s"Your name is $name" 

serviceImplメソッドは、無名関数を返します。 "(name)=> s"Your name is $name""は、Function2 [String、String] traitの単なるインスタンスです。

しかし、上記のように、無名関数がサービス特性をどのように実装していますか?

これはどのように変換されますか?

+0

反射ベースのダックタイピング+ Javaラムダの契約の組み合わせのために動作します。 –

+0

ヒント:Scala 2.12.xを使用しない限り、これはうまくいきません – Suma

答えて

5

これは新機能ですが2.12のリリースノートで説明しますhttp://www.scala-lang.org/news/2.12.0#lambda-syntax-for-sam-types

Scalaの2.12型チェッカーがFunctionNに加えて、任意の単一抽象メソッド(SAM)タイプのための有効な式として関数リテラルを受け入れ標準ライブラリからの型。これにより、ScalaコードからJava 8用に書かれたライブラリを使用する経験が向上します。

scala> val f =() => println("Faster!") 
scala> val fasterRunnable: Runnable = f 
<console>:12: error: type mismatch; 
found :() => Unit 
required: Runnable 

言語仕様がありますのみラムダ式は、SAM型のインスタンス、FunctionNタイプの任意のない表現に変換され

scala> val r: Runnable =() => println("Run!") 
r: Runnable = $$Lambda$1073/[email protected] 
scala> r.run() 
Run! 

注:ここでjava.lang.Runnableのを使用してREPLの例でありますSAM変換のための要件の完全なリスト。

デフォルトのメソッドを使用すると、Scalaの組み込みFunctionN特性がSAMインターフェイスにコンパイルされます。これは、Javaの独自のラムダ構文を使用してJavaからScalaの関数を作成することができます:

public class A { 
    scala.Function1<String, String> f = s -> s.trim(); 
} 

専門機能クラスもSAMインタフェースであり、パッケージscala.runtime.java8で見つけることができます。

型チェックの改良により、呼び出されたメソッドがオーバーロードされている場合でもラムダ式のパラメータ型を省略することができます。詳細は#5307を参照してください。両方の方法が適用可能であるけれども、以下でより詳細に説明するように、オーバーロード解決は、機能1の引数の型を持つものを選択

scala> trait MyFun { def apply(x: Int): String } 
scala> object T { 
    | def m(f: Int => String) = 0 
    | def m(f: MyFun) = 1 
    | } 
scala> T.m(x => x.toString) 
res0: Int = 0 

留意されたい。次の例では、コンパイラはラムダのパラメータタイプINTを推定します。

関連する問題