You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala match匹配顺序疑问:Cons分支为何不可达且sum恒为0?

Scala自定义List的sum方法中Cons分支不可达、始终返回0的问题解决

你的问题根本不是case分支顺序的问题,而是Scala模式匹配的标识符解析规则导致的:

在Scala中,模式匹配里的小写字母开头的标识符会被当作变量绑定——也就是说,你写的case mNil =>其实是把传入的任何mList实例都绑定到名为mNil的变量上,后面的case Cons(h, t)自然就永远不会被执行,所以不管你传入什么列表,sum方法都会直接返回0,IDEA也会提示Cons分支不可达。

而书中的Nil是大写开头的case object,所以case Nil =>会正确匹配对应的空列表对象,不会被当作变量。

解决方法有两种,选一种就行:

方法一:遵循Scala命名规范,把空列表对象改成大写开头(推荐)

把case object mNil改成case object MNil,然后在match和apply方法里统一使用MNil:

sealed trait mList[+A]
case object MNil extends mList[Nothing]
case class Cons[+A] (head:A, tail:mList[A]) extends mList[A]

object mList {
  def sum(ints: mList[Int] ): Int = ints match {
    case MNil => 0
    case Cons(h, t) => h + sum(t)
  }

  def apply[A](as: A*): mList[A] =
    if (as.isEmpty) MNil
    else Cons(as.head, apply(as.tail:_*))
}

方法二:保留小写名称,用反引号包裹标识符

如果不想改名,就在match分支里用反引号把mNil包起来,告诉Scala这是一个已有的常量对象,不是要绑定的变量:

sealed trait mList[+A]
case object mNil extends mList[Nothing]
case class Cons[+A] (head:A, tail:mList[A]) extends mList[A]

object mList {
  def sum(ints: mList[Int] ): Int = ints match {
    case `mNil` => 0
    case Cons(h, t) => h + sum(t)
  }

  def apply[A](as: A*): mList[A] =
    if (as.isEmpty) mNil
    else Cons(as.head, apply(as.tail:_*))
}

两种方法都能解决你的问题,不需要调换case分支的顺序。

内容的提问来源于stack exchange,提问作者Moeda Chaos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:50:23