通过将myClass作为参数

时间:2019-06-25 11:15:44

标签: scala

所以我有一个课:

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
}

3 个答案:

答案 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
}