【问题标题】:Explicit parameters out of scope in constructor's implicit parameter list?构造函数的隐式参数列表中的显式参数超出范围?
【发布时间】:2015-11-10 16:20:33
【问题描述】:

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


为了说明,让我们制作一些对象。此处的目的是创建幻像类型的层次结构以“标记”对象的层次结构。我希望隐含的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 没有任何区别。

【问题讨论】:

  • 作为一个普通的类 ctor 参数,t 是不可见的。试试(val t: ...)(x: t.DependentType)
  • @cchantep 添加val 似乎没有任何改变。 (我最初使用了一个案例类。)你的意思是让我也改变第二个参数列表吗?

标签: scala class scope implicit


【解决方案1】:

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

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

该类现在接受一个类型参数,该参数必须是Token 的子类型。当限制Token 允许的类型时,隐含证据可以通过type 参数引用具体Token 中的Phantom 类型。

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)
       ^

【讨论】:

  • 感谢您的解决方法。添加类型参数可能是正确的方法,尽管我一直希望避免这种情况,因为类型参数有一种在整个程序中“转移”的方式。不过,令人高兴的是,我现在知道将对象层次结构映射到特征层次结构是可行的!
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2015-02-19
相关资源
最近更新 更多