【问题标题】:Constructor's implicit parameter list can't refer to explicit argument?构造函数的隐式参数列表不能引用显式参数?
【发布时间】:2025-11-26 02:40:02
【问题描述】:

对于函数,隐式参数可以有一个arg.type,其中arg 在显式参数列表中。但显然,不是一个类:

Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_51).

scala> trait Applicable[A]
defined trait Applicable

scala> def f(a: AnyRef)(implicit ev: Applicable[a.type]): a.type = ???
f: (a: AnyRef)(implicit ev: Applicable[a.type])a.type

scala> case class Kniption(a: AnyRef)(implicit ev: Applicable[a.type])
<console>:8: error: not found: value a
       case class Kniption(a: AnyRef)(implicit ev: Applicable[a.type])
                                                              ^
<console>:8: error: type mismatch;
 found   : Applicable[a.type]
 required: Applicable[a.type]
       case class Kniption(a: AnyRef)(implicit ev: Applicable[a.type])
                                               ^

这是错误还是功能?如果这种行为有意义,您能解释一下原因吗?

【问题讨论】:

标签: scala constructor implicit path-dependent-type singleton-type


【解决方案1】:

看起来在 scala 的类定义中没有足够的信息来进行类型推断。 如何定义 Kniption 参数化:

case class Kniption[T](a: T)(implicit ev: Applicable[T])

【讨论】:

  • 这行得通,但我不想添加类型参数,因为这样我就必须在程序中我有一个 Kniption 对象的任何地方声明类型参数。我希望能够只引用普通的 Kniption 对象并假设每个对象都有一个适当的 Applicable 对象。
  • 你可以这样做:sealed trait AnyKniption { type Arg &lt;: AnyRef } 然后case class Kniption[T &lt;: AnyRef](a: T)(implicit ev: Applicable[T]) extends AnyKniption { type Arg = T }。现在您可以不带参数地引用AnyKniption 并获得arg 的精确类型:Kniption#Arg