Scala 隐式参数通过传递一个函数作为参数来感受adnvatage
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18854829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala Implicit parameters by passing a function as argument To feel the adnvatage
提问by ses
I try to feel the advantage of implicitparameters in Scala. (EDITED: special case when anonymous function is used. Please look at the links in this question)
尝试感受一下implicitScala中参数的优势。(已编辑:使用匿名函数时的特殊情况。请查看此问题中的链接)
I try to make simple emulation based on thispost. Where explained how Actionworks in PlayFramework. This also related to that.
我尝试根据这篇文章进行简单的模拟。哪里解释了如何Action在PlayFramework. 这也和那个有关。
The following code is for that purpose:
以下代码用于此目的:
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
}
I want to get "1" printed.
我想打印“1”。
How to avoid passing magic "2" but use "1" that was defined implicitly?
如何避免传递魔法“2”但使用隐式定义的“1”?
Also see the casewhere we do not use implicitin definition, but it is there, because of anonymous function passing with implicit.
另请参阅我们在定义中不使用的情况implicit,但由于匿名函数使用implicit.
EDITED:Just in case, I'm posting another example - simple emulation of how Play' Actionworks:
编辑:为了以防万一,我发布了另一个例子 - 简单模拟 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)
}
回答by edofic
Implicits don't work like this. There is no magic. They are just (usually) hidden parameters and are therefore resolved when invoking the function.
隐式不会像这样工作。没有魔法。它们只是(通常)隐藏的参数,因此在调用函数时会被解析。
There are two ways to make your code work.
有两种方法可以使您的代码工作。
you can fix the implicit value for all invocations of fun
您可以修复所有调用的隐式值 fun
def fun(block: Int=>String): String = {
block(implicitly[Int])
}
implicitlyis a function defined in Predef. Again no magic. Here's it's definition
implicitly是在 Predef 中定义的函数。再次没有魔法。这是它的定义
def implicitly[A](implicit value: A) = value
But this means it will resolve the implicit value when declaringthe funand not for each invocation.
但是,这意味着什么时候会解决的隐含价值声明的fun,而不是每次调用。
If you want to use different values for different invocations you will needto add the implicit paramter
如果要为不同的调用使用不同的值,则需要添加隐式参数
def fun(block: Int=>String)(implicit value: Int): String = {
block(value)
}
This will now depend on the implicit scope at the call site. And you can easily override it like this
现在这将取决于调用站点的隐式作用域。你可以像这样轻松地覆盖它
val result = fun{ _.toString }(3)
and result will be "3"because of the explicit 3at the end. There is, however, no way to magically change the funfrom your declaration to fetch values from implicit scope.
结果将是"3"因为3最后的显式。但是,没有办法神奇地fun将声明中的更改为从隐式范围中获取值。
I hope you understand implicits better now, they can be a bit tricky to wrap your head around at first.
我希望你现在更好地理解隐式,一开始可能有点棘手。
回答by ses
It seems that for that particular case I asked, the answer might be like this:
似乎对于我问的那个特殊情况,答案可能是这样的:
That this is not really a good idea to use implicit intValueor implicit requestalong with implicitly()using only oneparameter for the function that accept (anonymous) function.
那这是不是真的用一个好主意,implicit intValue或者implicit request沿implicitly()只使用一个参数接受(匿名)函数的函数。
Why not, because:
为什么不呢,因为:
Say, if in block(...)in apply()I would use implicitly[Request], then
it does not matter whether I use "implicit request"or not - it will use
request that is defined implicitly somewhere. Even if I would pass my
own request to Action { myOwnRequest =Result }.
说,如果在 block(...)中apply()我会使用implicitly[Request],那么我是否使用“隐式请求”并不重要 - 它会使用在某处隐式定义的请求。即使我将自己的请求传递给Action { myOwnRequest =Result }.
For that particular case is better to use curryingand two argumentsand.. in the second argument - (first)(second) to use implicit
对于这种特殊情况,最好在第二个参数中使用curryingand two argumentsand.. - (first)(second) to useimplicit
Like this:
像这样:
def apply(block:Request => Result)(implicit request:Request):Action2
See my little effortaround this example/use case here.
在此处查看我围绕此示例/用例所做的一点努力。
But, I don't see any good example so far in regards to how to use implicitby passing the (anonymous) function as argument (my initial question):
但是,到目前为止,我没有看到任何关于如何implicit通过将(匿名)函数作为参数传递来使用的好例子(我最初的问题):
fun{ implicit intValue => {intValue.toString}
or that one (updated version):
或者那个(更新版本):
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}

