我应该如何处理';匹配可能并不详尽';Scala警告?

我应该如何处理';匹配可能并不详尽';Scala警告?,scala,Scala,在将我的代码从2.12升级到Scala 2.13时,我收到了一系列这样的警告: [warn] /mystuff/ScalaJack/core/src/main/scala/co.blocke.scalajack/model/TypeAdapterCache.scala:100:40: match may not be exhaustive. [warn] It would fail on the following input: Nil [warn] va

在将我的代码从2.12升级到Scala 2.13时,我收到了一系列这样的警告:

[warn] /mystuff/ScalaJack/core/src/main/scala/co.blocke.scalajack/model/TypeAdapterCache.scala:100:40: match may not be exhaustive.
[warn] It would fail on the following input: Nil
[warn]                     val head :: tail = factories
(工厂是某种类型T的列表)

这不是匹配语句,这是一个赋值。我同意编译器的说法,如果工厂为零,这将失败,但是做这个赋值的更好方法是什么

val head :: tail = factories
虽然这不是一个
match
表达式,但它确实涉及到对模式
head::tail
进行模式匹配
factories
,如果
factories
Nil
,则可能会失败

解决方案是安全地拆分列表,然后处理可能的错误:

val (head, tail) = factories.splitAt(1)

head
将是一个
列表,因此可能为空,因此请使用
isEmpty
进行测试,或使用
headOption
转换为
选项,然后使用标准的
选项
方法对其进行处理。

在这种情况下,如果输入为
Nil
,操作将失败。如果您知道列表不能为空,可以使用cats中的
NonEmptyList
类型:。否则,在这种情况下,您可以使用模式匹配更清楚地表达您的意图,例如:

val(头、尾)=工厂匹配{
案例h::t=>(h,t)
case Nil=>???//根据需要处理空列表
}

除了Ethan的解释之外,代码可以按如下方式重构

factories match {
  case head::tail => // your original code
  case Nil => // handle it or leave as _ 
}

虽然这是创建新的两个新值,但这是一种模式匹配形式。如果编译是正确的,它可能会失败。如果你确信列表可能永远不会是空的,或者考虑禁用警告或使用“或…”不是一个很好的解释,我们总是在答案中加上解释。请给你的答案加上一些解释,这样别人就可以从中学习。