繁体   English   中英

函数类型定义中隐式的scala

[英]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版本中) 隐式函数类型

参见奥德斯基本人的拉取请求1775

让我们通过将最后一个参数部分移到等号的右边来稍微完善一下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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM