[英]How to avoid using asInstanceOf in Scala
Currently my code needs class casting 目前我的代码需要类转换
val dataWriter: BytesDataWriter = createDataWriter
def createDataWriter(p: SomeClass) =
p.create_datawriter().asInstanceOf[BytesDataWriter]
The create_datawriter
method will return the superclass DataWriter. create_datawriter
方法将返回超类DataWriter。 Instead of casting it using asInstanceOf
, I tried this approach 我尝试了这种方法,而不是使用
asInstanceOf
进行转换
val dataWriter: BytesDataWriter = createDataWriter(p) match {
case writer: BytesDataWriter => writer
case _ => throw new ClassCastException
}
This is too verbose, and in case case does not work. 这太冗长了,如果情况不起作用。 Is there a better alternative to class casting?
是否有更好的替代类铸造?
You would use the second approach in case you can do something with a non- BytesDataWriter
result, or to get a better error message: 如果您可以使用非
BytesDataWriter
结果执行某些 BytesDataWriter
,或者为了获得更好的错误消息,您将使用第二种方法:
val dataWriter: BytesDataWriter = p.create_datawriter() match {
case writer: BytesDataWriter => writer
case other => throw new Exception(s"Expected p to create a BytesDataWriter, but got a ${other.getClass.getSimpleName} instead!")
}
Otherwise, use asInstanceOf
. 否则,请使用
asInstanceOf
。
The answer from Alexey Romanov is a good advice for your specific situation. Alexey Romanov的答案对于您的具体情况是一个很好的建议。 Alternatively you could try to avoid this situation by changing the sctructure of the surrounding code.
或者,您可以通过更改周围代码的结构来避免这种情况。
When you are using a class and instantiate it, it looks like you are implementing some kind of configurable dependency handling. 当您使用类并实例化它时,看起来您正在实现某种可配置的依赖项处理。 This is a complex problem, but fortunately there are some good solutions for this:
这是一个复杂的问题,但幸运的是有一些很好的解决方案:
You could use some kind of dependency injection and inject the needed ByteDataWriter
with the specialized type. 您可以使用某种依赖注入并使用专用类型注入所需的
ByteDataWriter
。 Look at the "Robot Leg" example described in the Google Guice FAQ on how to deal with different variants of the same base class, and on how to deal with generics . 查看Google Guice FAQ中描述的“机器人腿”示例,了解如何处理同一基类的不同变体,以及如何处理泛型 。 This might help you to avoid your problem with
DataWriter
and ByteDataWriter
. 这可以帮助您避免
DataWriter
和ByteDataWriter
问题。
You can also access your DataWriter
with a protocol (or in Scala speak: a strucutral type ). 您还可以使用协议访问
DataWriter
(或者在Scala中使用: 结构类型 )。 Structural typs will not be checked at compile time, so no need for a class cast. 在编译时不会检查结构类型,因此不需要类强制转换。
Or you can handle you dependencies using a Scala specialty: The cake pattern . 或者您可以使用Scala专业处理依赖项: 蛋糕模式 。 With this pattern you can compose your class just as needed.
有了这种模式,您可以根据需要撰写课程。 You can design the class needing the
ByteDataWriter
completely type safe. 您可以设计需要
ByteDataWriter
的类完全类型安全。 The compiler will then make sure, that it can only combined with the correct class. 然后编译器将确保它只能与正确的类组合。 No need for a class cast.
不需要课堂演员。 The disadvantage is, that you cannot reconfigure the dependencies using a config file.
缺点是,您无法使用配置文件重新配置依赖项。 But usually this is not necessary, because the supported variants are well known at compile time.
但通常这不是必需的,因为支持的变体在编译时是众所周知的。
If you have the option, consider to re-design your code using one of the methods described above, to get rid of the class cast. 如果您有选项,请考虑使用上述方法之一重新设计代码,以摆脱类强制转换。 It is very likely that you will have the same problem on many other places in your code.
很可能您在代码中的许多其他位置都会遇到同样的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.