Lambdas 的 Scala 隐式转换
Scala Implicit conversion for Lambdas
我试图从 link - http://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html 中理解隐式函数类型,下面是一个示例代码作为示例。在下面的代码中,我们首先创建一个 class 事务。
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
它不起作用。
我无法理解为什么即使类型为 Transaction 的 thisTransaction 出现在它没有被使用的范围内?
op
是 Transaction => T
类型,而不是(不幸的是,我认为不可能指定它)implicit Transaction => T
.
所以它的 Transaction
类型的参数不能被隐式提供。它必须是一个显式参数。 (只能隐式提供标记为 implicit
的参数列表中函数的参数。)
计划在 Scala 的未来版本中使用隐式函数类型。据我所知,连下一个版本(2.13)都没有。
目前,您只能在 Dotty 中使用它们。
这里用 dotty 0.4.0-RC1 编译得很好:
def transaction[T](op: implicit Transaction => T) = {
implicit val trans: Transaction = new Transaction
op
trans.commit()
}
我想从博客的介绍中应该很清楚post,这是Odersky为了消除Dotty编译器实现中的一些样板而发明的新特性,引用:
For instance in the dotty compiler, almost every function takes an implicit context parameter which defines all elements relating to the current state of the compilation.
目前Scala的主流版本好像没有这个。
编辑
(在评论中回答 follow-up 问题)
如果我对博客 post 的理解正确,它会被脱糖成类似
的内容
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[...]{}
是一个匿名本地 class。基本 class ImplicitFunction1
是这个新功能,它类似于普通 lambda 的 Function
,但有 implicit
个参数。
我试图从 link - http://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html 中理解隐式函数类型,下面是一个示例代码作为示例。在下面的代码中,我们首先创建一个 class 事务。
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
它不起作用。
我无法理解为什么即使类型为 Transaction 的 thisTransaction 出现在它没有被使用的范围内?
op
是 Transaction => T
类型,而不是(不幸的是,我认为不可能指定它)implicit Transaction => T
.
所以它的 Transaction
类型的参数不能被隐式提供。它必须是一个显式参数。 (只能隐式提供标记为 implicit
的参数列表中函数的参数。)
计划在 Scala 的未来版本中使用隐式函数类型。据我所知,连下一个版本(2.13)都没有。
目前,您只能在 Dotty 中使用它们。
这里用 dotty 0.4.0-RC1 编译得很好:
def transaction[T](op: implicit Transaction => T) = {
implicit val trans: Transaction = new Transaction
op
trans.commit()
}
我想从博客的介绍中应该很清楚post,这是Odersky为了消除Dotty编译器实现中的一些样板而发明的新特性,引用:
For instance in the dotty compiler, almost every function takes an implicit context parameter which defines all elements relating to the current state of the compilation.
目前Scala的主流版本好像没有这个。
编辑
(在评论中回答 follow-up 问题)
如果我对博客 post 的理解正确,它会被脱糖成类似
的内容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[...]{}
是一个匿名本地 class。基本 class ImplicitFunction1
是这个新功能,它类似于普通 lambda 的 Function
,但有 implicit
个参数。