4

Play! を読みながら フレームワークのドキュメント、私はこのスニペットに出くわしました:

def index = Action { implicit request =>
  session.get("connected").map { user =>
    Ok("Hello " + user)
  }.getOrElse {
    Unauthorized("Oops, you are not connected")
  }
}

ドキュメンテーションはそこで説明しimplicitます:

または、リクエストから暗黙的にセッションを取得することもできます

その上、私はこの投稿を読みました: Literal with Implicit論理的には、関数は暗黙的なパラメーターを持つことができないようです。

私がよく理解した場合、これはメソッドとは対照的に、関数には常に契約(インターフェース)があるためです。

実際、たとえば、Function1[Int, Function1[Int, Int]]戻り値の型の最初のパラメーターとして anがあるIntため、これに として注釈を付けることができませんimplicit。これは、高レベルの戻り値の型について混乱を招く可能性があります:() => IntまたはInt => Int ...

したがって、 firstActionの必須パラメーターはリテラル関数であるため、前のスニペット コードが暗黙的に動作するもの。

Action.apply()コンパイラがこのコードを受け入れることを許可する理由は、メソッドの複数の署名であると思います。

  • def apply(block: Request[AnyContent] => Result): Action[AnyContent]
  • def apply(block: => Result): Action[AnyContent](最初のものにリダイレクト)

2 番目はパラメーターを必要としないため、これはリテラル関数の暗黙のパラメーターの存在下で選択されますか?

4

1 に答える 1

6

次のコードを検討してください。

class MyImplicitClass(val session: Int)
object Tester {
  def apply(fun: MyImplicitClass => Int): Int = ???
  def apply(fun: => Int): Int = ???
}
Tester { implicit myImplicitClass => session * 20}

この関数の場合:

def session(implicit myImplicitClass: MyImplicitClass): Int = myImplicitClass.session

がスコープ内にある場合、最初のコード スニペットがコンパイルされます。これは、 fieldにアクセスするために暗黙的なパラメーターが関数myImplicitClassに渡され、フィールド アクセスを省略できることが明らかであるためです。これぞまさにトリック・ザ・プレイ!フレームワークが使用しています。機能を確認してください。 session myImplicitClass.sessionControllersession

補足として、上記のクロージャーは、暗黙的なパラメーターを取ることを述べているのではなく、次のことを行う必要を回避するための言語機能です。

Tester { myImplicitClass => 
  implicit val x = myImplicitClass
  session * 20
}

クロージャーの本体でクロージャーパラメーターを暗黙の値として使用したい場合。また、Scala 2.9 の時点では、このトリックのパラメーターが 1 つだけのクロージャーに制限されていることにも注意してください。

于 2013-01-11T01:18:03.860 に答える