当前位置: 首页 > 知识库问答 >
问题:

理解Scala中的隐式

吕冠宇
2023-03-14

我在学习Scala playframework教程时遇到了一段令我迷惑不解的代码:

def newTask = Action { implicit request =>
taskForm.bindFromRequest.fold(
        errors => BadRequest(views.html.index(Task.all(), errors)),
        label => {
          Task.create(label)
          Redirect(routes.Application.tasks())
        } 
  )
}

于是我决定调查一下,偶然发现了这个帖子。

implicit def double2Int(d : Double) : Int = d.toInt
def double2IntNonImplicit(d : Double) : Int = d.toInt

共有1个答案

百里涛
2023-03-14

我将在下面解释implicits的主要用例,但要了解更多细节,请参阅Scala编程的相关章节。

隐式参数

方法上的最终参数列表可以标记为implicit,这意味着这些值将从调用它们的上下文中获取。如果scope中没有正确类型的隐式值,则不会编译。由于隐式值必须解析为单个值,并且为了避免冲突,最好使类型特定于其用途,例如,不要要求您的方法查找一个隐式int

  // probably in a library
class Prefixer(val prefix: String)
def addPrefix(s: String)(implicit p: Prefixer) = p.prefix + s

  // then probably in your application
implicit val myImplicitPrefixer = new Prefixer("***")
addPrefix("abc")  // returns "***abc"

当编译器为上下文找到错误类型的表达式时,它将查找允许它TypeCheck的类型的隐式function值。因此,如果需要a并且它找到b,它将在作用域中查找b=>a类型的隐式值(它还检查其他一些地方,如ba伙伴对象(如果存在的话)。由于defs可以“ETA扩展”为function对象,因此隐式def xyz(arg:B):a也可以。

因此,您的方法之间的区别在于,当找到double但需要int时,编译器将为您插入标记为implicit的方法。

implicit def doubleToInt(d: Double) = d.toInt
val x: Int = 42.0

工作原理与

def doubleToInt(d: Double) = d.toInt
val x: Int = doubleToInt(42.0)
apply(block: (Request[AnyContent]) ⇒ Result): Action[AnyContent]
request => ...

在函数文本中,=>之前的部分是一个值声明,如果需要,可以将其标记为Implicit,就像在任何其他val声明中一样。在这里,request不必标记为implicit以便进行类型检查,但通过这样做,它将作为隐式值提供给函数中可能需要它的任何方法(当然,它也可以显式使用)。在这种特定情况下,之所以这样做是因为Form类上的BindFromRequest方法需要一个隐式Request参数。

 类似资料:
  • 我试图创建一个简洁的结构,用于理解基于未来的业务逻辑。下面是一个示例,其中包含一个基于异常处理的工作示例: 然而,这可能被视为一种非功能性或非Scala的处理方式。有更好的方法吗? 请注意,这些错误来自不同的来源——有些在业务级别(“检查所有权”),有些在控制器级别(“授权”),有些在数据库级别(“找不到实体”)。因此,从单一常见错误类型派生它们的方法可能不起作用。

  • 我有三个连续的未来,并在理解中使用 现在我有一个像List[Future[T]这样的未来列表,首先我使用这种方法将其转移到Future[List[T]](为什么这个未来列表到未来列表的转换编译和工作?)。然后我得到未来

  • 我正在阅读Scala Cookbook(http://shop.oreilly.com/product/0636920026914.do) 有一个与未来使用相关的例子,涉及理解。 到目前为止,我对理解的理解是,当与一个集合一起使用时,它会产生另一个相同类型的集合。例如,如果每个< code>futureX的类型为< code>Future[Int],则以下内容也应为< code>Future[In

  • 问题内容: 我遇到了这个老问题,并使用scala 2.10.3进行了以下实验。 我重写了Scala版本以使用显式尾递归: 并将其与以下Java版本进行了比较。我有意识地使函数成为非静态的,以便与Scala进行公平的比较: 这是我计算机上的结果: 这是(Java HotSpot(TM)64位服务器VM,Java 1.7.0_51)上的scala 2.10.3。 我的问题是,scala版本的隐藏成本是

  • 我想在我的play scala Web应用程序中进行错误处理。 我的应用程序与数据库对话以获取一些行,它遵循以下流程。 < li >首先调用数据库以获取一些数据 < li >使用第一次调用中的数据从数据库中提取其他数据 < li >使用从最近两次db调用中收到的数据形成响应。 下面是我的伪代码。 以上理解中的每一个方法都返回一个未来,这些方法的签名如下。 在以下情况下,我该如何进行错误/故障处理

  • 本文向大家介绍scala中的隐式类型转换的实现,包括了scala中的隐式类型转换的实现的使用技巧和注意事项,需要的朋友参考一下 Scala语言中的隐式转换是一个十分强大的语言特性,主要可以起到两个作用: 一.自动进行某些数据类型的隐式转换 String类型是不能自动转换为Int类型的,所以当给一个Int类型的变量或常量赋予String类型的值时编译器将报错。所以,一下语句是错误的。 如果需要将一个