模式匹配-值不是绑定变量的成员



我正在使用Scala(ver.2.13.2(,在这里我定义了一个具有特征ListSeq的简单链表。此外,我想覆盖一个toString方法来进行漂亮的打印。为此,我决定使用模式匹配。在assert的情况下可以看到期望的结果

sealed trait ListSeq {
override def toString: String = s"[$elemSequence]"
private def elemSequence: String = {
this match {
case ListPair(hd, tl @ ListPair(_, _)) => s"$hd, ${tl.elemSequence}"
case ListPair(hd, EmptyList) => s"$hd"
case EmptyList => ""
}
}
}
case class ListPair(head: Int, tail: ListSeq) extends ListSeq
case object EmptyList extends ListSeq
object ListSeqExample extends App {
val seq1 = ListPair(1, ListPair(2, ListPair(3, EmptyList)))
val seq2 = EmptyList

assert(seq1.toString == "[1, 2, 3]")
assert(seq2.toString == "[]")
}

问题

此代码未编译,错误为:

value elemSequence is not a member of ListPair
case ListPair(hd, tl @ ListPair(_, _)) => s"$hd, ${tl.elemSequence}"

我不清楚为什么会出现这个错误。据我所知,Scala可以在嵌套字段上进行匹配,并将字段绑定到一个变量——就像case ListPair(hd, tl @ ListPair(_, _))中所做的那样。但从错误消息来看,它似乎无法猜测绑定对象(ListPair(的类型

怪异的行为

另一件有趣的事情是-如果我以以下方式重新定义ListSeq-通过删除elemSequence方法,并且所有字符串创建都在toString中完成-没有错误

sealed trait ListSeq {
override def toString: String = this match {
case ListPair(hd, tl @ ListPair(_, _)) => s"$hd, ${tl.toString}"
case ListPair(hd, EmptyList) => s"$hd"
case EmptyList => ""
}
}

我知道toString的结果会略有不同(没有大括号(,但这不是重点。

问题

为什么在一种情况下会出现错误,而在另一种情况中却能愉快地编译?

它返回一个错误,因为elemSequence是在ListSeq中定义的private方法,所以它在ListPair中不可见。

一种解决方案可能是将可见性更改为protected(并添加修饰符final,使子类不能override该方法(:

sealed trait ListSeq {
override def toString: String = s"[$elemSequence]"
final protected def elemSequence: String = {
this match {
case ListPair(hd, tl @ ListPair(_, _)) => s"$hd, ${tl.elemSequence}"
case ListPair(hd, EmptyList) => s"$hd"
case EmptyList => ""
}
}
}
case class ListPair(head: Int, tail: ListSeq) extends ListSeq
case object EmptyList extends ListSeq
object ListSeqExample extends App {
val seq1 = ListPair(1, ListPair(2, ListPair(3, EmptyList)))
val seq2 = EmptyList

assert(seq1.toString == "[1, 2, 3]")
assert(seq2.toString == "[]")
}

它是一个私有方法。这些子类(在Scala或Java中(不能继承或访问。

将其更改为protected、public或package private将解决此问题。

相关内容

  • 没有找到相关文章

最新更新