Scala 隐式参数通过传递一个函数作为参数来感受adnvatage [英] Scala Implicit parameters by passing a function as argument To feel the adnvatage

查看:36
本文介绍了Scala 隐式参数通过传递一个函数作为参数来感受adnvatage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试感受隐式参数在Scala中的优势.(已编辑:使用匿名函数时的特殊情况.请查看此问题中的链接)

我尝试根据这篇帖子进行简单的模拟.哪里解释了 Action 如何在 PlayFramework 中工作.这也与那个有关.>

以下代码用于此目的:

object ImplicitArguments extends App {隐式 val intValue = 1//这是将隐式传递给可能使用它的每个人的退出值def fun(block: Int=>String): String = {//我们在这里不使用 _implicit_ !块(2)//??如何避免传递 '2' 但利用它会被隐式传递?}//这里我们使用 _implicit_ 关键字让它知道应该传递值!val 结果 = fun{ 隐式 intValue =>{//这是我的块"intValue.toString//(这是匿名函数)}}println(result)//打印 2}

我想打印1".

如何避免传递魔法2"而使用隐式定义的1"?

另请参阅案例,其中我们不使用implicit 在定义中,但它在那里,因为匿名函数通过 implicit 传递.

以防万一,我将发布另一个示例 - Play' Action 如何工作的简单模拟:

 object ImplicitArguments extends App {案例类请求(味精:字符串)隐式 val request = Request("我的请求")案例类结果(味精:字符串)案例类操作(结果:结果)对象动作{def apply(block:Request => 结果):Action = {val result = block(...)//这里应该是什么??新动作(结果)}}val action = Action { 隐式请求 =>Result("得到请求 [" + request + "]")}打印(动作)}

解决方案

隐式不能这样工作.没有魔法.它们只是(通常)隐藏的参数,因此在调用函数时会被解析.

有两种方法可以让您的代码正常工作.

您可以修复所有 fun 调用的隐含值

def fun(block: Int=>String): String = {块(隐式[Int])}

implicitly 是在 Predef 中定义的函数.再次没有魔法.这是它的定义

def 隐式[A](隐式值:A) = 值

但这意味着它会在声明fun而不是每次调用时解析隐式值.

如果你想为不同的调用使用不同的值,你需要添加隐式参数

def fun(block: Int=>String)(隐含值:Int): String = {块(值)}

这将取决于调用站点的隐式作用域.您可以像这样轻松覆盖它

val 结果 = fun{ _.toString }(3)

并且结果将是 "3" 因为在末尾显式 3.但是,没有办法神奇地更改声明中的 fun 以从隐式作用域中获取值.

我希望你现在更好地理解隐式,一开始可能有点难以理解.

I try to feel the advantage of implicit parameters in Scala. (EDITED: special case when anonymous function is used. Please look at the links in this question)

I try to make simple emulation based on this post. Where explained how Action works in PlayFramework. This also related to that.

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.

How to avoid passing magic "2" but use "1" that was defined implicitly?

Also see the case where we do not use implicit in definition, but it is there, because of anonymous function passing with implicit.

EDITED: Just in case, I'm posting another example - simple emulation of how Play' Action works:

  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)

}

解决方案

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

def fun(block: Int=>String): String = { 
  block(implicitly[Int]) 
}

implicitly is a function defined in Predef. Again no magic. Here's it's definition

def implicitly[A](implicit value: A) = value

But this means it will resolve the implicit value when declaring the fun and not for each invocation.

If you want to use different values for different invocations you will need to 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 3 at the end. There is, however, no way to magically change the fun from your declaration to fetch values from implicit scope.

I hope you understand implicits better now, they can be a bit tricky to wrap your head around at first.

这篇关于Scala 隐式参数通过传递一个函数作为参数来感受adnvatage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆