gpt4 book ai didi

scala - Scala 类型系统如何知道 cons + Nil 是详尽无遗的?

转载 作者:行者123 更新时间:2023-12-04 22:59:32 25 4
gpt4 key购买 nike

我刚刚写了这个函数,想知道如果我省略了 Nil 情况会发生什么,并注意到 scalac 给了我一个警告:

def printList[String](list: List[String]) {
list match {
case head :: tail => {
println(head)
printList(tail)
}
//case Nil => println("Done")
}
}
Warning: match may not be exhaustive.
It would fail on the following input: Nil

我无法确切地确定这里发生了什么。我对递归数据类型的模式匹配有了大致的了解,直到你穷尽所有的情况,但我不清楚它是如何映射到 Scala 类型系统的。具体来说,我正在查看 Scala 标准库的源代码并想知道:
  • Scala 在代码中的哪里确切地认为需要基本案例来完成 List 类实例的匹配语句?人们当然可以想象一种没有基本情况的“继续前进”的代数数据类型。
  • 代码中的什么地方是 scala.collection.immutable.Nil 特别指定为 List 类的基本情况?
  • 最佳答案

    其实没有你想的那么复杂。 Listsealed abstract class正好有两个实现,Nil:: (是的,这是类(class)的名称)。这里的重要部分是 sealed修饰符。这只是强制任何实现 List 的类。必须与 List 位于同一源文件中本身。
    sealed的重要性现在编译器肯定知道 List 的每个可能的实现者,因此如果您对列表进行模式匹配,编译器可以确定您的模式匹配块是否详尽。

    最后要意识到的一件事是 :: 中存在一些语法糖。 .通常,如果您有一些案例类:

    case class Foo(a: String, b: Int)

    你会这样匹配
    x match {
    case Foo(a, b) => //...
    }

    然而,当你有一个只有两个成员的 case 类时,你也可以这样写:
    x match {
    case a Foo b => //...
    }

    所以在你的模式匹配语句中,你真的在​​做:
    list match {
    case ::(head, tail) => {

    所以实际上你所做的就是检查 list 是否是 :: 的一个实例.因此,编译器可以看到您从不检查 list 是否是 Nil 的实例。并警告你。

    关于scala - Scala 类型系统如何知道 cons + Nil 是详尽无遗的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30043433/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com