所以我有一个课:
case class Document (idx: String, name: String, code: String)
由于进行了一些转换,最初创建为Document的对象现在变为Any类型。
val doc = Document("12", "anyName", "ps") // Ends up as type Any
所以我想再次将其转换为类型Document
。
我知道可以这样做:
val docNew = doc.asInstanceOf[Document]
但是,我正在尝试将类型(在这种情况下为Document
)作为参数,以使其更通用。
所以我尝试了以下操作:
val mType = Document
val docNew = doc.asInstanceOf[mType]
但是Intellij说:
无法解析符号mType
编辑:我的最终目标是将参数Document
传递给函数,因此最后我可以做类似的事情:
def convertIntoDoc(doc: Any, mType: Type) = {
val docNew = doc.asInstanceOf[mType]
docNew
}
答案 0 :(得分:5)
如果您想学习使用Scala进行编程,则必须了解类型和值之间的区别。
由于类型擦除类型参数从未真正进入程序中。实际上,仅存在类型可以帮助您编写良好的代码。
如果您走这条路,您最终会意识到asInstanceOf[T]
实际上并没有做任何事情。
您可能会认为这很奇怪,并且可以通过类型擦除来避免类型系统的使用,但是让我向您保证,它非常有用,并且当涉及到更复杂的代码时,实际上已成为通用编程的垫脚石 em>,例如代码由于类型参数化而可以以多种不同方式使用。
要进一步旋转它,几乎应该永远不要以val
类型的Any
结尾,因为您将失去静态类型的此附加安全网。这意味着您已经在代码上游的某个地方犯了一个错误。
您的最终目标很容易实现:
def convertIntoDoc[MType](doc: Any) = {
val docNew = doc.asInstanceOf[MType]
docNew
}
您只需要记住MType
是类型而不是变量。因此,它必须用作类型参数而不是值参数。
问题在于,如果使用错误的类型,将Any
转换为MType
会得到ClassCastException
(运行程序时!)。
asInstanceOf
非常危险,因为它会覆盖Scala编译器提供的类型安全性。
如果对此有任何疑问,请告诉我。
答案 1 :(得分:2)
将Any
转换为Document
的正确方法是使用match
:
val docNew = doc match { case d: Document => d }
这是安全的,因为如果由于某种原因该对象不是MatchException
类型,它将抛出Document
。
您的convertIntoDoc
函数只是asInstanceOf
的包装,因此您需要详细说明此函数的作用(最好在单独的问题中)。
答案 2 :(得分:-1)
您可以使用val
代替type
type mType = Document
val docNew = doc.asInstanceOf[mType]
对于问题的第二部分,您可以使用type参数作为参数来传递类型
def convertIntoDoc[A](doc: Any) = {
val docNew = doc.asInstanceOf[A]
docNew
}