2013-06-25 193 views
0

我是使用scala的新手。 我试图使用模式与反射匹配:scala Class.forName模式匹配

abstract class Person{ 
val name:String, 
val age:Int 
} 
case class Man (name:String,age:Int,workPlace:String) extends Person 

val aclass = Class.forName("man") 
aclass match{ 
case m:Man => println("this is a man class") 
case p:Person => println("Person") 
case _ => println("Nothing") 
} 

我总是得到默认的一部分(“无”),并以正确的匹配(MAN)。我究竟做错了什么 ?

谢谢

+1

难道只是问题一个错字或你没事用'抛出java.lang.ClassNotFoundException:在您的实际代码man'(Java类名称区分大小写)?顺便说一句,你的Person类甚至不应该因逗号而编译。 –

回答

5

首先,您需要使用完整和适当的类名称。其次,Class.forName返回一个Class[_],而不是您给它的类的一个实例。看看我对代码所做的修改以获得更清晰的图像:

abstract class Person { 
    val name: String //removed comma 
    val age: Int 
    } 

    case class Man(name: String, age: Int, workPlace: String) extends Person 

    val manClassName = classOf[Man].getName //get the proper name of the class 

    println("Man class name: %s".format(manClassName)) 

    val aclass = Class.forName(manClassName) //returns Class[Man] 

    aclass match { 
    case m: Class[Man] => println("this is a man class") //Pattern match on Class[Man] 
    case p: Class[Person] => println("Person") 
    case _ => println("Nothing") 
    } 
+0

谢谢,这工作!顺便说一句,[class]是什么? – igx

+0

这只是一种表示Class是类型构造函数并且需要一个类型的方法。所以你的情况是Class [Man]。 – Noah

0

代码很少出现问题。也许我不明白你在用Class.forName(String)做什么,所以我改变了一些东西。

首先,这些的用例类,以便让你的getter和setter进行封装。

sealed trait Person 
case class Man (name:String,age:Int,workPlace:String) extends Person 

接下来,Class.forName返回一个Class,而不是一个对象。 所以,你需要通过调用人

的构造
val man = Man("Jo", 24, "anywhere") 

然后实例可以在所有的模式匹配:

man match{ 
case m:Man => println("this is a man class") 
case p:Person => println("Person") 
case _ => println("Nothing") 
} 

它会击中第一种情况相符,但这样必须确保所订购的人,个人情况如何你想要他们。 对于反射,你会想看看类型标签和ClassTags

http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html