简体   繁体   English

如何将Scala中的对象强制转换为其自身类型和任何不相关特征的交集?

[英]How can an object in Scala be cast to the intersection of its own type and any unrelated trait?

Consider the following: 考虑以下:

trait Foo { def bar: Any }

Now, 3 and X don't even have a method bar yet this compiles: 现在, 3X甚至没有方法bar但这个编译:

val a = 3.asInstanceOf[Int with Foo]

object X
val b = X.asInstanceOf[X.type with Foo]

This code, when compiled and run (on Scala 2.10.3), produces no error. 编译和运行此代码(在Scala 2.10.3上)不会产生错误。 However, the following will compile cleanly but will produce a ClassCastException at runtime: 但是,以下干净地编译,但会在运行时生成ClassCastException

val a1 = a.asInstanceOf[Foo]
val b1 = b.asInstanceOf[Foo]

How can this be? 怎么会这样? I can almost accept the fact that no static analysis/checking is performed on explicit casts, and they're discouraged and usually unneeded anyway—although I do think Scala could emit a warning about a definitely incorrect type cast given that there is no way object X can ever have the trait Foo , nor an integer—however I can't easily accept the fact that an integer can be cast at runtime to an intersection type containing a completely irrelevant and non-empty trait. 我几乎可以接受这样一个事实,即没有对显式强制转换执行静态分析/检查,并且它们不鼓励并且通常不需要 - 尽管我认为Scala 可以发出关于绝对不正确的类型转换的警告,因为没有object X可以有特征Foo ,也不是整数 - 但是我不能轻易接受这样一个事实,即整数可以在运行时转换为包含完全不相关非空特征的交集类型。

The problem is that JVM doesn't support intersection types, so there is no obvious runtime equivalent to asInstanceOf[Int with Foo] . 问题是JVM不支持交集类型,因此没有明显的运行时等效于asInstanceOf[Int with Foo] This is basically the same issue as asInstanceOf[T] , where T is a generic parameter (both in Scala and equivalent Java): you also have the cast which appears to succeed at runtime but actually inserts casts in later code which uses methods of T . 这与asInstanceOf[T]基本相同,其中T是一个通用参数(在Scala和等效的Java中):你也有一个看似在运行时成功的强制转换,但实际上在后来的代码中插入强制转换使用了T方法。

One possibility would be to compile the cast to Int with Foo as two casts to Int and to Foo , but this doesn't quite work in general (eg when there is no runtime cast to Foo itself, or when the value is passed to methods which take Int with Foo ). 一种可能性是编译投地Int with Foo作为两个强制类型转换来IntFoo ,但是这一般不相当的工作(例如,当没有运行时投来Foo本身,或当值传递给方法其中采用Int with Foo )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM