[英]scala implicit in function type definition
我有以下抽象类:
abstract class FieldProvider[+T: Writes](db: DB)(implicit i: RequestAction, j: ExecutionContext) {}
以及以下实现:
class LengthProvider extends FieldProvider ...
object LengthProvider extends ((DB) => LengthProvider) {
def apply(v1: DB): LengthProvider = new LengthProvider(v1)
}
class WidthProvider extends FieldProvider ...
object WidthProvider extends ((DB) => WidthProvider) {
def apply(v1: DB): WidthProvider = new WidthProvider(v1)
}
之所以拥有这些apply
方法,是因为我需要以下配置图:
val providers: Map[String, ((DB) => FieldProvider)] = Map(
"length" -> LengthProvider,
"width" -> WidthProvider
)
这样我就可以通过包含提供者名称的字符串来初始化提供者:
providers("length")(db) // returns a new instance of LengthProvider
现在,我的问题是所有这些提供程序构造函数都需要两个隐式变量。 但是我不知道如何将其包含在函数定义(DB) => FieldProvider
。 因此,从本质上讲, apply
方法签名应该类似于(DB)(implicit RequestAction, ExecutionContext) => FieldProvider
,但是我不知道我尝试执行的语法是否正确。
我也可以放弃并明确传递它们:
object WidthProvider extends ((DB, RequestAction, ExecutionContext) => WidthProvider) {
def apply(v1: DB, v2: RequestAction, v3: ExecutionContext): WidthProvider = new WidthProvider(v1)(v2,v3)
}
但是然后我必须将它们显式传递给其他地方,而不是providers("length")(db)
,而必须编写providers("length")(db, implicitly[RequestAction], implicitly[ExecutionContext])
,感觉不对。
假设FieldProvider
有2个需要隐式的方法。 避免重复的更方便方法是将它们作为构造函数级别的隐式参数传递,然后FieldProvider
所有内部方法都可以“共享”它们。
但是,这对您当前的类树没有帮助,因此请解决此问题,而不要这样做:
abstract class FieldProvider()(implicit param1: X1..) {
def test: T = param1.doSomething
}
只需将隐式移动到方法级别,以便您可以在与扩展构造函数不同的时间提供它。
abstract class FieldProvider() {
def test()(implicit param1: X1): T = param1.doSomething
}
因此,从本质上讲,
apply
方法签名应该类似于(DB)(implicit RequestAction, ExecutionContext) => FieldProvider
,但是我不知道我尝试执行的语法是否正确。
请注意,您可能会直接获得(在将来的Scala 2017版本中) 隐式函数类型 。
让我们通过将最后一个参数部分移到等号的右边来稍微完善一下
f1
的定义:
def f1(x: Int) = { implicit thisTransaction: Transaction =>
thisTransaction.println(s"first step: $x")
f2(x + 1)
}
现在,此新版本的f1的右侧是隐式函数值。
此值的类型是什么?
以前是Transaction => Int
,也就是说,该函数具有隐式参数的知识已在类型中丢失。pull请求实现的主要扩展是引入隐式函数类型,这些类型反映了我们已经拥有的隐式函数值。
具体来说,新型的f1是:
implicit Transaction => Int
就像普通的函数类型语法
A => B
,对scala.Function1[A, B]
,隐式函数类型语法implicit A => B
避免对scala.ImplicitFunction1[A, B]
。
其他职能领域也是如此。 随着dotty的拉取请求#1758的合并,此类功能的上限不再为22。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.