scalaでは暗黙的に次のように動作します:
コンバータ
パラメーター値インジェクター
Implicitの使用には3つのタイプがあります
暗黙的な型変換:エラー生成割り当てを意図した型に変換します
val x:String = "1"
val y:Int = x
StringはIntのサブタイプではないため、2行目でエラーが発生します。エラーを解決するために、コンパイラーは、暗黙のキーワードを持ち、引数としてStringを取り、Intを返すスコープ内でそのようなメソッドを探します。
そう
implicit def z(a:String):Int = 2
val x :String = "1"
val y:Int = x // compiler will use z here like val y:Int=z(x)
println(y) // result 2 & no error!
暗黙的なレシーバー変換:通常、レシーバー呼び出しオブジェクトのプロパティによって、たとえば メソッドまたは変数。したがって、レシーバーが任意のプロパティを呼び出すには、プロパティがそのレシーバーのクラス/オブジェクトのメンバーである必要があります。
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
mahadi.haveTv // Error happening
ここでmahadi.haveTvはエラーを生成します。Scalaコンパイラーはまず、マハディレシーバーのhaveTvプロパティを探します。見つかりません。次に、Mahadiオブジェクトを引数として取り、Johnnyオブジェクトを返す暗黙のキーワードを持つスコープ内のメソッドを探します。しかし、ここにはありません。したがって、エラーが発生します。しかし、以下は大丈夫です。
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
implicit def z(a:Mahadi):Johnny = new Johnny
mahadi.haveTv // compiler will use z here like new Johnny().haveTv
println(mahadi.haveTv)// result Sony & no error
暗黙的なパラメータインジェクション:メソッドを呼び出し、そのパラメータ値を渡さないと、エラーが発生します。Scalaコンパイラーはこのように機能します。最初に値を渡そうとしますが、パラメーターの直接の値は取得しません。
def x(a:Int)= a
x // ERROR happening
2番目のパラメータは、それがどんな探します暗黙のキーワードがある場合はヴァルにスコープ持っている同じタイプ値のを。取得できない場合、エラーが発生します。
def x(implicit a:Int)= a
x // error happening here
パラメータaに暗黙のキーワードがあるため、この問題を解決するために、コンパイラはIntのタイプを持つ暗黙のvalを探します。
def x(implicit a:Int)=a
implicit val z:Int =10
x // compiler will use implicit like this x(z)
println(x) // will result 10 & no error.
もう一つの例:
def l(implicit b:Int)
def x(implicit a:Int)= l(a)
次のように書くこともできます
def x(implicit a:Int)= l
ためlは有する暗黙パラメータとの範囲に方法Xの身体、ある暗黙的なローカル変数(パラメータがローカル変数である)のパラメータであり、xは、そうでのxの本体方法メソッドシグネチャLの暗黙の引数の値は、あります提出されたXメソッドのローカル暗黙の変数(パラメータ)暗黙のうちに。 a
そう
def x(implicit a:Int)= l
このようなコンパイラになります
def x(implicit a:Int)= l(a)
もう一つの例:
def c(implicit k:Int):String = k.toString
def x(a:Int => String):String =a
x{
x => c
}
ので、エラーの原因となるCにX {X => C}は、引数または暗黙ヴァルに明示的に価値の通過を必要とする範囲内。
したがって、メソッドxを呼び出すときに、関数リテラルのパラメーターを明示的に暗黙的にすることができます。
x{
implicit x => c // the compiler will set the parameter of c like this c(x)
}
これはPlay-Frameworkのアクションメソッドで使用されています
in view folder of app the template is declared like
@()(implicit requestHreader:RequestHeader)
in controller action is like
def index = Action{
implicit request =>
Ok(views.html.formpage())
}
明示的に暗黙的に要求パラメーターについて言及しない場合は、次のように記述されている必要があります。
def index = Action{
request =>
Ok(views.html.formpage()(request))
}