加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 案例类的自定义提取器在模式匹配中不起作用

发布时间:2020-12-16 09:04:38 所属栏目:安全 来源:网络整理
导读:考虑一个案例类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
考虑一个案例类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
}

会无效的.此代码段会给出错误:

error: method u is defined twice;
the conflicting method u was defined at line 12:7

因此,您必须使用自己的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方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读