gpt4 book ai didi

scala - Scala Cons 模式匹配如何确定 List 的头部和尾部?

转载 作者:行者123 更新时间:2023-12-04 15:44:03 26 4
gpt4 key购买 nike

下面的语句中头尾是如何确定的:

 val head::tail = List(1,2,3,4);
//head: 1 tail: List(2,3,4)

不应该有一些代码将第一个元素提取为头部并将尾部作为新列表返回。我一直在梳理 Scala 标准库代码,但我无法找到/理解这是如何/在哪里完成的。

最佳答案

这里涉及的 Scala 构造是 Extractor .符号 :: 只不过是 Scala 中的一个案例类,其中一个 unapply方法存在于其伴随对象上,以使提取魔术发生。 Here是一个很好的关于提取器的深入教程。但这里是总结:

每当您想“解压”类的内容时,无论是用于变量绑定(bind)还是作为模式匹配的一部分,编译器都会查找方法unapply。在表达式左侧的任何符号上。这可能是一个对象、一个案例类伴随对象(如您的问题中的 :: )或具有 unapply 的实例. unapply 的参数是要解包的传入类型,返回类型是 Option已声明为预期结构和类型的内容。在模式匹配 None表示未找到匹配项。在变量绑定(bind)中 MatchError如果 None 则抛出是结果。

一个很好的思考方式unapply是它是 apply 的倒数吗? .在哪里 unapply函数调用语法的接收者,unapply是提取器调用的接收者。

为了进一步说明这一点,让我们定义一个简单的案例类:

case class Cat(name: String, age: Int)

因为它是一个案例类,所以我们会自动生成 applyunapply伴随对象上的方法,大致如下所示:
object Cat {
// compiler generated...
def apply(name: String, age: Int) = new Cat(name, age)
def unapply(aCat: Cat): Option[(String, Int)] = Some((aCat.name, aCat.age))
}

当您创建 Cat通过伴随对象 apply叫做。当您打开 Cat 的组成部分时, unapply叫做:
val mycat = Cat("freddy", 3) // `apply` called here
...
val Cat(name, age) = mycat // `unapply` called here
...
val animal: AnyRef = mycat
val info = animal match {
case Cat(name, age) => "My pet " + name // `unapply` called here
case _ => "Not my pet"
}
// info: String = My pet freddy

因为 unapply返回 Option ,我们有很大的能力来编写处理更有趣的情况的提取器,例如,在提取值之前测试传入的类型是否符合某些标准。例如,假设我们想要获取“老”猫的名字。有人可能会这样做:
object OldCatName {
def unapply(aCat: Cat) = if (aCat.age >= 10) Some(aCat.name) else None
}

用法与生成的 unapply 相同:
val yourcat = Cat("betty", 12)
...
val OldCatName(name1) = yourcat
// name1: String = "betty"
val OldCatName(name2) = mycat
// scala.MatchError: Cat(freddy,3) (of class Cat)
MatchError s 不是一件好事,所以让我们使用模式匹配:
val conditions = Seq(mycat, yourcat) map { 
case OldCatName(oldie) => s"$oldie is old"
case Cat(name, age) => s"At age $age $name is not old"
}
// conditions: Seq[String] = List(At age 3 freddy is not old, betty is old)
unapply 所涉及的额外一点魔法 :: 的方法是一些语法糖允许 val ::(head, tail) = ...待写 val head :: tail = ...反而。

关于scala - Scala Cons 模式匹配如何确定 List 的头部和尾部?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25944688/

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