我试图从链接中理解隐式函数类型 - http://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html,下面是一个示例代码作为示例。在下面的代码中,我们首先创建一个类Transaction。
class Transaction {
private val log = scala.collection.mutable.ListBuffer.empty[String]
def println(s: String): Unit = log += s
private var aborted = false
private var committed = false
def abort(): Unit = { aborted = true }
def isAborted = aborted
def commit(): Unit =
if (!aborted && !committed) {
Console.println("******* log ********")
log.foreach(Console.println)
committed = true
}
}
接下来我定义了两个方法f1和f2,如下所示
def f1(x: Int)(implicit thisTransaction: Transaction): Int = {
thisTransaction.println(s"first step: $x")
f2(x + 1)
}
def f2(x: Int)(implicit thisTransaction: Transaction): Int = {
thisTransaction.println(s"second step: $x")
x
}
然后定义一个方法来调用函数
def transaction[T](op: Transaction => T) = {
val trans: Transaction = new Transaction
op(trans)
trans.commit()
}
lambda下面用于调用代码
transaction {
implicit thisTransaction =>
val res = f1(3)
println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
}
我的问题是,如果我将val trans: Transaction = new Transaction
更改为implicit val thisTransaction = new Transaction
并将op(trans)
更改为op
则无效。
我无法理解为什么即使在范围内存在此类事务的事务,它还没有被使用?
答案 0 :(得分:1)
op
的类型为Transaction => T
,而不是(我认为不可能指定此内容)implicit Transaction => T
。
因此无法隐式提供类型Transaction
的参数。它必须是一个明确的论点。 (只能隐式提供标记为implicit
的参数列表中的函数的参数。)
答案 1 :(得分:1)
为未来版本的Scala计划隐式函数类型。据我所知,甚至没有下一个版本(2.13)。
目前,您只能在Dotty中使用它们。
答案 2 :(得分:1)
这里用dotty 0.4.0-RC1编译得很好:
def transaction[T](op: implicit Transaction => T) = {
implicit val trans: Transaction = new Transaction
op
trans.commit()
}
我认为从博客文章的介绍中可以清楚地看到,这是Odersky发明的一个新功能,用于消除Dotty编译器实现中的一些样板,引用:
例如在dotty编译器中,几乎每个函数都采用一个隐式上下文参数,该参数定义了与编译当前状态相关的所有元素。
目前在Scala的主流版本中似乎没有。
修改强>
(回答评论中的后续问题)
如果我正确地理解了博客文章,那么它就会变成像
这样的东西transaction(
new ImplicitFunction1[Transaction, Unit] {
def apply(implicit thisTransaction: Transaction): Unit = {
val res = f1(args.length)(implicit thisTransaction:Transaction)
println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
}
}
)
new ImplicitFunction1[...]{}
是一个匿名的本地类。基类ImplicitFunction1
是这个新功能,类似于普通lambda的Function
,但带有implicit
个参数。