scala – 案例类的自定义提取器在模式匹配中不起作用
考虑一个案例类Person
case class Person(firstName: String,lastName: String,middleName: Option[String]) object Person { def apply(firstName: String,lastName: String): Person = new Person(firstName,lastName,None) def unapply(arg: Person): Option[(String,String)] = Some(arg.firstName,arg.lastName) } val person = Person("firstName","lastName") person match { case Person(firstName,lastName) => Console.println(firstName + " " + lastName) } 在与case类编译器的模式匹配中给出了一个错误:模式匹配中的参数数量错误,但是当我使用类而不是case类时它的工作. class Person(val firstName: String,val lastName: String,middleName: Option[String]) 我在这里理解的是,我们不能为case类使用自己的自定义提取器,但可以使用自己的构造函数(apply).请解释我这种奇怪的行为. 这是一个ScalaFiddle来测试:https://scalafiddle.io/sf/HvxvdAZ/0 解决方法
您的自定义unapply与自动生成的unapply冲突,因为它具有相同的名称和相同的参数类型(只有返回类型不同).所以,由于同样的原因,这是无效的
class A { def u(i: Int): Int = i def u(i: Int): String = "int" + i } 会无效的.此代码段会给出错误:
因此,您必须使用自己的unapply定义一个单独的提取器对象(类似于对象FirstLast {def unapply(…)…}),或省略类声明中的大小写. 单独的提取器对象 这是一个(在我看来相对优雅)的方式: case class Person( firstName: String,middleName: Option[String] ) object Person { def apply( firstName: String,lastName: String ): Person = new Person(firstName,None) object FirstLast { def unapply(arg: Person): Option[(String,String)] = Some((arg.firstName,arg.lastName)) } } val person = Person("firstName","lastName") person match { case Person.FirstLast(firstName,lastName) => Console.println(firstName + " " + lastName) } 省略案例,实施自己的不适用 如果你想完全替换原来的unapply,那么你可以这样做: class Person( val firstName: String,val middleName: Option[String] ) object Person { def apply( firstName: String,middleName: Option[String] ): Person = new Person(firstName,middleName) def apply( firstName: String,None) def unapply(arg: Person): Option[(String,String)] = Some((arg.firstName,arg.lastName)) } val person = Person("firstName","lastName") person match { case Person(firstName,lastName) => Console.println(firstName + " " + lastName) } 但同样,它只允许一个单独的应用.使用单独的提取器来使用多个unapply方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |