Scala:没有明确的类型参数的Typecast

请考虑以下示例:

case class C[T](x:T) {
  def f(t:T) = println(t)
  type ValueType = T
}

val list = List(1 -> C(2),"hello" -> C("goodbye"))

for ((a,b) <- list) {
  b.f(a)
}

在这个例子中,我知道(运行时保证)一个类型将是一些T,而b将具有相同T的类型C [T].当然,编译器不知道,因此我们得到一个输入错误BF(a)中.

要告诉编译器这个调用是OK的,我们需要做一个类型转换àla b.f(a.asInstanceOf [T]).不幸的是,T在这里是不知道的.所以我的问题是:如何重写b.f(a)以使此代码编译?

我正在寻找一个不涉及复杂构造(保持代码可读)的解决方案,而且这是一个“干净”的意思,我们不应该依赖代码删除来使其工作(请参阅下面的第一种方法).

我有一些工作方法,但是由于各种原因我觉得他们不满意.

我试过的方法

b.asInstanceOf[C[Any]].f(a)

这是有用的,并且是可读的,但它是基于“谎言”. b不是C [Any]类型,我们没有得到运行时错误的唯一原因是因为我们依赖于JVM的限制(类型擦除).我认为只有使用x.asInstanceOf [X]才是很好的风格,当我们知道x真的是X型.

b.f(a.asInstanceOf[b.ValueType])

这应该是根据我对类型系统的理解而工作的.我已经将成员ValueType添加到C类,以便能够明确地引用类型参数T.然而,在这方法中我们得到一个神秘的错误信息:

Error:(9,22) type mismatch;
 found   : b.ValueType
    (which expands to)  _1
 required: _1
  b.f(a.asInstanceOf[b.ValueType])
                    ^

为什么?似乎抱怨我们期望类型_1,但得到类型_1! (但是即使这种方法有效,它也限于我们有可能将成员ValueType添加到C的情况.如果C是一些现有的库类,那么我们也不能这样做).

for ((a,b) <- list.asInstanceOf[List[(T,C[T]) forSome {type T}]]) {
  b.f(a)
}

一个工作,并且语义正确(即,当调用asInstanceOf时,我们不会“说谎”).限制是这有点不可读.此外,它对当前情况有些具体:如果a,b不是来自同一个迭代器,那么我们可以在哪里应用此类型转换? (此代码也对Intelli / J IDEA 2016.2过于复杂的副作用,它将其显示为编辑器中的错误.)

val (a2,b2) = (a,b).asInstanceOf[(T,C[T]) forSome {type T}]
  b2.f(a2)

我会期望这个工作,因为a2,b2现在应该有类型T和C [T]相同的存在T.但我们得到一个编译错误

Error:(10,9) type mismatch;
 found   : a2.type (with underlying type Any)
 required: T
  b2.f(a2)
       ^

为什么? (除此之外,这种方法的缺点是由于一对的创建和销毁而导致运行时费用(我认为).)

b match {
    case b : C[t] => b.f(a.asInstanceOf[t])
  }

这个工作.但是使用匹配来封装代码可使代码的可读性变得更差. (对于Intelli / J来说也是太复杂了)

解决方法

最干净的解决方案是IMO,您使用类型捕获模式匹配发现的解决方案.您可以通过将模式直接集成在您的理解中,使其简洁明了,并希望可读,如下所示:

for ((a,b: C[t]) <- list) {
  b.f(a.asInstanceOf[t])
}

小提琴:http://www.scala-js-fiddle.com/gist/b9030033133ee94e8c18ad772f3461a0

如果你不是在理解,不幸的是,相应的模式分配不起作用:

val (c,d: C[t]) = (a,b)
d.f(c.asInstanceOf[t])

这是因为在第二行,t不再是范围了.在这种情况下,您必须使用完整的模式匹配.

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...