关于 Scala 隐含多个类型参数的问题

Posted

技术标签:

【中文标题】关于 Scala 隐含多个类型参数的问题【英文标题】:Question about Scala implicits with multiple type parameters 【发布时间】:2021-08-30 18:41:58 【问题描述】:

我很难理解与“找不到隐含价值”错误相关的错误。这是一个突出错误的最小示例。

sealed trait BehaviourA
final case object A1 extends BehaviourA
final case object A2 extends BehaviourA

sealed trait BehaviourB
final case object B1 extends BehaviourB
final case object B2 extends BehaviourB

trait factory[O<:BehaviourA, R<:BehaviourB] ... 

// Define an implicit value for each combination of the two behaviours
object factory 
  implicit val behaviour1 = new factory[A1, B1]  ... 
  ... (one for each Ai, Bj)


object genElement 
  import factory._

  def apply[O <: BehaviourA, R<:BehaviourB](...)(implicit c: factory[O, R])

但是,当我尝试从另一个方法调用它时,它会抱怨在 genExample 中找不到隐式 c 的值。

def callerMtd[T<:BehaviourA]()
  genElement[T, B1](...)


or 

def callerMtd[T<:BehaviourA, R<:BehaviourB]()
  genElement[T, R](...)

如果我像下面这样直接调用它们,那很好。为什么我不能在调用者方法中使用类型参数?

def callerMtd()
  genElement[A1, B2](...)

【问题讨论】:

【参考方案1】:

即使类型是密封的,并且您似乎提供了所有类型类实例

(Ai、Bj 各一个)

这并没有涵盖类型边界指定的所有可能情况

def callerMtd[T <: BehaviourA, R <: BehaviourB]

例如,这里有一些适合边界的类型,但您可能没有为它们提供实例

callerMtd[A1.type with A2.type, B1.type with B2.type]

为了确保编译器可以为factory[T, R] 调用一个实例,其中T &lt;: BehaviourAR &lt;: BehaviourB 您必须指示它如何使用相应的隐式def 生成它

implicit def foo[T <: BehaviourA, R <: BehaviourB]

【讨论】:

非常感谢!但是具有单个类型参数的相同代码可以工作。这种情况下编译器会自动插入隐式def吗? @idwx 单类型参数情况和多类型参数情况应该没有太大区别。如果您的问题仍然存在,请准备一个最小示例。

以上是关于关于 Scala 隐含多个类型参数的问题的主要内容,如果未能解决你的问题,请参考以下文章

Scala在匹配多个案例类时提取参数以进行理解

scala关于HelloWorld的简解

参数 'e' 隐含了一个 'any' 类型 React TypeScript

找不到 ^ 类型的证据参数的隐含值

反应/打字稿:参数“道具”隐含了“任何”类型错误

Spark Scala 程序中的隐含功能不起作用