为何Scala中使用对象类型的匹配类型计算结果等同于Nothing
Scala匹配类型对
Nil.type的匹配逻辑说明 核心原因
这个现象是Scala标准库中Nil的类型定义,和匹配类型(Match Type)的子类型匹配规则共同作用的结果:
- 首先明确
Nil的类型定义:Scala标准库中Nil是表示空列表的单例对象,官方定义为object Nil extends List[Nothing],因此它的单例类型Nil.type是List[Nothing]的子类型,而List[+A]实现了IterableOnce[+A]特质,所以Nil.type <:< IterableOnce[Nothing](Nil.type是IterableOnce[Nothing]的子类型)的关系是成立的。 - 匹配类型的匹配规则是从上到下按顺序做子类型匹配,而非要求类型完全相等,只要输入类型是case后类型的子类型就会命中该分支,不会继续匹配后续分支。
具体匹配过程
对Elem[Nil.type]的匹配流程如下:
- 第一个分支
case String => Char:Nil.type不是String的子类型,匹配失败,跳过。 - 第二个分支
case IterableOnce[t] => t:Nil.type是IterableOnce[Nothing]的子类型,匹配成功,类型参数t被推断为Nothing,直接返回t即Nothing。 - 后续的
Array[t]分支和兜底分支case ? => X都不会被触发。
因此summon[Elem[Nil.type] =:= Nothing]可以编译通过,不会走到兜底分支返回Nil.type。
如果要让Nil.type命中兜底分支,要么调整分支顺序把IterableOnce[t]移到兜底分支之后(不推荐,会覆盖所有非String/Array的IterableOnce子类型的匹配逻辑),要么修改匹配规则为精确匹配,只匹配和IterableOnce[t]完全相等的类型。
内容的提问来源于stack exchange,提问作者bbarker
相关产品推荐
相关产品推荐

