2013-01-11 67 views
4

在閱讀Play時!文字函數的隱式參數

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

Documentation解釋implicit有:框架文件,我碰到這個片段來

或者,你可以從一個請求隱含檢索會話

此外,我看到這篇文章: Literal with Implicit並且從邏輯上來說這個函數不能有隱式參數。

如果我也想通了,這是因爲功能,違背方法有始終合同(接口)。

確實,例如,Function1[Int, Function1[Int, Int]]具有返回類型的第一個參數Int,因此阻止我們將其標註爲implicit。這將導致有關其高級別返回類型的困惑:() => IntInt => Int ...

因此,什麼前面的代碼段與內隱的行爲,因爲需要先Action的參數是文字功能。

我想的原因,允許編譯器接受這個代碼是Action.apply()方法的多個簽名:

  • def apply(block: Request[AnyContent] => Result): Action[AnyContent]
  • def apply(block: => Result): Action[AnyContent](重定向到第一個)

由於第二沒有按不需要一些參數,是否在文字函數的隱式參數存在的情況下選擇了這個參數?

回答

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 

在範圍上,則第一代碼片段將編譯,因爲顯然隱含參數myImplicitClass將被傳遞給函數session爲了訪問字段myImplicitClass.session,允許您省略字段訪問。這正是Play的訣竅! Framework正在使用,請檢查Controller以查找session函數。

作爲一個側面說明,上述封閉不說,它需要一個隱含的參數,它是一種語言功能,以避免必須做到以下幾點:

Tester { myImplicitClass => 
    implicit val x = myImplicitClass 
    session * 20 
} 
當一個人想使用閉包參數作爲

封閉體內的隱含價值。另外請注意,從Scala 2.9開始,你只能使用這個技巧的一個參數關閉。

+0

我沒有玩!目前與我一起在電腦上安裝,所以不幸的是,我無法進一步瞭解爲什麼這個與Play!編譯,我設置了一個層次結構像Play一樣!並且無法弄清楚「你可以通過請求隱式地獲得會話」,然後直接從請求中刪除訪問並直接引用會話......這可能只是他們文檔中的錯誤,但我不是非常肯定。 –

+0

我正在寫一個可能的答案(對我自己的問題:)) – Mik378

+0

在我的示例中,隱式請求=>與隱式測試=>相同。另外,用你的替換調用它是沒有意義的,因爲它是一個函數的參數,而不是一個值。我將其重命名爲「myImplicitClass」以使其更加清晰。 –