Scalaで複数の暗黙の引数を使用して関数リテラルを定義するにはどうすればよいですか?私はこの方法を試しました:
def create = authAction { (implicit request, user) ⇒ // Syntax error
Ok(html.user.create(registrationForm))
}
ただし、コンパイルエラーがスローされます。
Scalaで複数の暗黙の引数を使用して関数リテラルを定義するにはどうすればよいですか?私はこの方法を試しました:
def create = authAction { (implicit request, user) ⇒ // Syntax error
Ok(html.user.create(registrationForm))
}
ただし、コンパイルエラーがスローされます。
前の回答で述べたように、関数リテラルに対して定義できる暗黙のパラメーターは1つだけですが、回避策があります。
複数の暗黙的な引数の代わりに、それぞれ1つの引数を持つ複数の引数リストを取るように関数リテラルを記述できます。次に、各引数を暗黙としてマークすることができます。元のスニペットの書き換え:
def create = authAction { implicit request ⇒ implicit user ⇒
Ok(html.user.create(registrationForm))
}
から呼び出すことができauthAction
ますf(request)(user)
。
implicit
キーワードの重複は煩わしいですが、少なくともそれは機能します。
言語仕様について私が理解できることから、バージョン2.9.2の時点では、無名関数に対して1つの暗黙的なパラメーターしか定義できません。
例えば
val autoappend = {implicit text:String => text ++ text}
ちょうどあなたと同じような状況で、PlayにauthAction関数を実装すると、ユーザーを簡単に渡すことができます。ラムダが行ったように、カリー化することでそれを行うことができます。authAction
関数に暗黙的に受信させることになりRequestHeader
ましたが、リクエストとユーザーの両方を明示的に渡します。
def authAction(f: (RequestHeader, User) => Result)(implicit request: RequestHeader) = {
...
val authUser = loadUser(...)
f(request, authUser)
}
そしてそれを使用するには:
def create = authAction { (request, user) =>
Ok(html.user.create(registrationForm))
}
複数の暗黙的なパラメーターを使用して無名関数を定義する方法はありません。
@ pagoda_5bの回答と@paradigmaticのコメントを詳しく説明するために、Scala言語仕様のセクション6.23では、次のような無名関数を定義しています。
Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
ResultExpr ::= (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
Binding ::= (id | ‘_’) [‘:’ Type]
ご覧のとおり、パラメーターのリストまたは単一の暗黙的なパラメーターのいずれかを定義できます。
暗黙的に複数のパラメーターが必要な場合は、それらをカレーする必要があります。