构造函数的隐式参数列表中的显式参数超出范围?

时间:2015-08-17 21:59:57

标签: scala class scope implicit

在定义函数时,我可以创建一个隐式参数列表,该列表引用前面显式参数列表中的变量,但在定义类时则不行。我做错了吗?

为了说明,让我们制作一些对象。这里的目的是创建一个幻像类型的层次结构来“标记”对象的层次结构。我希望隐式ev保证对象来自正确的层次结构。

trait Token {
  type Phantom
}

object TopToken extends Token {
  trait Phantom
}

object SubToken extends Token {
  trait Phantom <: TopToken.Phantom
}

object ForeignToken extends Token {
  trait Phantom  // doesn't extend TopToken.Phantom
}

def f(t: Token)(implicit ev: t.Phantom <:< TopToken.Phantom) { println(t) }

函数f正常工作:

scala> f(SubToken)
$line5.$read$$iw$$iw$SubToken$@76c2539f

scala> f(ForeignToken)  // This should fail.
<console>:12: error: Cannot prove that ForeignToken.Phantom <:< TopToken.Phantom.
              f(ForeignToken)
               ^

但请注意当我使用相同的参数列表来定义类时会发生什么:

scala> class F(t: Token)(implicit ev: t.Phantom <:< TopToken.Phantom)
<console>:9: error: not found: value t
       class F(t: Token)(implicit ev: t.Phantom <:< TopToken.Phantom)
                                      ^

我正在运行Scala 2.11.2。

更新进一步的实验表明,implicit没有任何区别。

1 个答案:

答案 0 :(得分:1)

如果您参数化F类,则可以使用以下语法实现此目的。

class F[T <: Token](t: T)(implicit ev: T#Phantom <:< TopToken.Phantom) { }

该类现在采用一个类型参数,该参数必须是Token的子类型。然后,在限制允许的Phantom类型时,隐式证据可以通过类型参数引用具体Token中的Token类型。

scala> class F[T <: Token](t: T)(implicit ev: T#Phantom <:< TopToken.Phantom) { }
defined class F

scala> new F(SubToken)
res1: F[SubToken.type] = F@6d26561b

scala> new F(ForeignToken)
<console>:15: error: Cannot prove that ForeignToken.Phantom <:< TopToken.Phantom.
       new F(ForeignToken)
       ^