繁体   English   中英

Scala - 这个 map + case 语法是什么?

[英]Scala - what is this map + case syntax?

我似乎无法找到有关此语言功能的更多信息,您可以在其中将case放入map ,如下所示:

   val sVersion = CrossVersion.partialVersion(scalaVersion)
      .map { case (major:Long, minor: Long) => s"_$major.$minor" } getOrElse ""

我已经开始使用这种语法,但它叫什么,我在哪里可以找到更多关于它的信息?

我已经开始使用这种语法,但它叫什么 […]

它的官方名称是匿名模式匹配 Function Scala 社区有时也将其称为Partial Function Literal

[...] 我在哪里可以找到更多信息?

Scala 编程语言中所有内容的最终真实来源是Scala 语言规范(又名SLS 您会注意到我已经链接到规范的 2.13 版——不幸的是,尚未发布 Scala 3 的单一综合规范。

有关所有详细信息,请参阅Scala 语言规范 8.5模式匹配匿名函数 简单地说,表达式

{
  case p1 => e1
  case p2 => e2
  // …
  case pn => en
}

相当于

(x1: S1, x2: S2, /* … */, xn: Sn) => (x1, x2, /* … */, xn) match {
  case p1 => e1
  case p2 => e2
  // …
  case pn => en
}

前提是结果类型可通过SAM 转换FunctionN[S1, S2, /* … */, Sn, R] ,或者作为特殊情况PartialFunction1[S1, R] (这是名称Partial Function Literal的来源。 )

在 Scala 3 中,有一个新特性可以使这段代码更加简洁: 很长一段时间以来, Scala 的设计者都希望统一TuplesArgument Lists 换句话说,他们想让 Scala 中的方法只接受一个参数,而这个参数是一个元组。 不幸的是,事实证明 a) 这极大地破坏了向后兼容性和 b) 极大地破坏了平台互操作性。

现在,Scala 3 是一个忽略问题 a) 的机会,但您不能忽略问题 b),因为 Scala 的主要设计目标之一是与底层主机平台(例如 .NET 在现在废弃的 Scala.NET,ECMASCript / HTML5 / DOM / WebAPI 平台,Scala.js,本机操作系统,Scala-native,或 Java 平台(JRE,JDK,JVM, J2SE、J2EE、Java、Kotlin、Clojure 等)在 Scala-JVM 的情况下)。

然而,Scala 的设计者设法找到了折衷方案,其中 arguments 和元组不是一回事,但参数可以很容易地转换为元组,而元组可以很容易地转换为 arguments。

这称为Parameter Untupling ,它基本上意味着类型FunctionN[S1, S2, /* … */, Sn, R]的 function 可以自动转换为类型Function1[(S1, S2, /* … */, Sn), R]Function1[TupleN[S1, S2, /* … */, Sn], R]的语法糖。

简单的说,

(p1: S1, p2: S2, /* … */, pn: Sn) => e: R

可以自动转换为

(x: (S1, S2, /* … */, Sn)) => {
  val p1: S1 = x._1
  val p2: S2 = x._2
  // …
  val pn: Sn = x._n

  e
}

这样,您的代码将如下所示:

val sVersion = CrossVersion.partialVersion(scalaVersion)
  .map { (major: Long, minor: Long) => s"_$major.$minor" } getOrElse ""

注意:不幸的是,目前还没有 Scala 3 的全面规范。 有部分语言参考,但仅描述了与 Scala 2 的差异。因此,您通常必须在 SLS 和 Scala 3 文档之间来回切换。

在Scala 2中,称为pattern-matching decomposition

请参阅: https://docs.scala-lang.org/scala3/reference/other-new-features/parameter-untupling.html

在Scala 3,你可以

val sVersion = CrossVersion.partialVersion(scalaVersion)
      .map { (major:Long, minor: Long) => s"_$major.$minor" } getOrElse ""

这通常称为“解构”或“解构绑定”(例如:在 Clojure https://clojure.org/guides/destructuring 中)。 Scala 使用模式匹配来实现这一点。

在您的示例中,您使用缩短的模式匹配来解构包含版本的Option 您也可以跳过显式Long类型声明。

关于这个主题的好读物:

https://www.oreilly.com/library/view/programming-scala-2nd/9781491950135/ch04.html https://docs.scala-lang.org/cheatsheets/index.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM