我尝试在Scala中感受implicit
参数的优势。 (已编辑:使用匿名函数时的特殊情况。请查看此问题中的链接)
我尝试根据this帖子进行简单的模拟。在Action
解释了PlayFramework
的工作原理。这也与that有关。
以下代码用于此目的:
object ImplicitArguments extends App {
implicit val intValue = 1 // this is exiting value to be passed implicitly to everyone who might use it
def fun(block: Int=>String): String = { // we do not use _implicit_ here !
block(2) // ?? how to avoid passing '2' but make use of that would be passed implicitly ?
}
// here we use _implicit_ keyword to make it know that the value should be passed !
val result = fun{ implicit intValue => { // this is my 'block'
intValue.toString // (which is anonymous function)
}
}
println(result) // prints 2
}
我想要打印“1”。
如何避免传递魔法“2”但使用隐含定义的“1”?
另请参阅我们在定义中不使用implicit
的{{3}},但它存在,因为匿名函数传递了implicit
。
编辑:
为了以防万一,我发布了另一个例子 - 简单模拟Play'Action
如何工作:
object ImplicitArguments extends App {
case class Request(msg:String)
implicit val request = Request("my request")
case class Result(msg:String)
case class Action(result:Result)
object Action {
def apply(block:Request => Result):Action = {
val result = block(...) // what should be here ??
new Action(result)
}
}
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}
println(action)
}
答案 0 :(得分:6)
Implicits不能像这样工作。没有魔力。它们只是(通常)隐藏的参数,因此在调用函数时会被解析。
有两种方法可以使代码正常工作。
您可以修复fun
def fun(block: Int=>String): String = {
block(implicitly[Int])
}
implicitly
是Predef中定义的函数。再一次没有魔力。这是它的定义
def implicitly[A](implicit value: A) = value
但这意味着当声明 fun
而不是每次调用时,它将解析隐含值。
如果要为不同的调用使用不同的值,将需要来添加隐式参数
def fun(block: Int=>String)(implicit value: Int): String = {
block(value)
}
现在这将取决于呼叫站点的隐式范围。你可以像这样轻松覆盖它
val result = fun{ _.toString }(3)
,结果将是"3"
,因为最后有明确的3
。但是,没有办法从声明中神奇地更改fun
以从隐式作用域中获取值。
我希望你现在能够更好地理解隐含的内容,起初可能有点棘手。
答案 1 :(得分:0)
对于我提出的那个特殊情况,似乎答案可能是这样的:
对于接受(匿名)的函数,仅使用一个参数implicit intValue
或implicit request
以及implicitly()
并不是一个好主意功能
为什么不呢,因为:
比方说,如果在lock(...)
中的apply()
我会使用implicitly[Request]
,那么
我是否使用“隐式请求”并不重要 - 它会使用
在某处隐式定义的请求。即使我会通过我的
自己对Action { myOwnRequest =Result }
的请求。
对于特定情况,最好在第二个参数中使用currying
和two arguments
和.. - (第一个)(第二个)使用implicit
像这样:
def apply(block:Request => Result)(implicit request:Request):Action2
在此处查看此示例/用例的little effort。
但是,到目前为止,我没有看到任何关于如何通过传递(匿名)函数作为参数来使用implicit
的好例子(我的初始问题):
fun{ implicit intValue => {intValue.toString}
或那个(更新版本):
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}