在这种情况下,scala 中模式匹配的目的是什么?

Kni*_*gTG 0 functional-programming scala

list = List((1,2), (3,4))
swapped_list = list.map{case (a, b) => (b, a)}
Run Code Online (Sandbox Code Playgroud)

我想知道这样做的目的case。这背后是否有设计原则或什么?

在一些类似的问题下,有人将其解释为偏函数的应用。但是,即使它们是对的,我们到底为什么还要使用偏函数呢?

IMO,写这个最自然的形式如下

swapped_list = list.map(x => (x._2, x._1))
Run Code Online (Sandbox Code Playgroud)

Jör*_*tag 7

在这种情况下,scala 中模式匹配的目的是什么?

这不完全是模式匹配。这就是Scala 语言规范所称的模式匹配匿名函数,但在社区中通常被称为部分函数文字

模式匹配匿名函数由具有几个块的case秒,但没有match表达。根据预期的结果类型,它定义了 aFunction或 a PartialFunction。确切的翻译将就像你在里面写了一个FunctionPartialFunction与模式匹配match表达式一样,即问题中的代码相当于

swapped_list = list.map(x => x match { case (a, b) => (b, a) })
Run Code Online (Sandbox Code Playgroud)

这又相当于:

swapped_list = list.map(
  new scala.Function2[Tuple2[Int, Int], Tuple2[Int, Int]] {
    def apply(x: Tuple2[Int, Int]): Tuple2[Int, Int] = x match {
      case (a, b) => new Tuple2[Int, Int](b, a) 
    }
  }
)
Run Code Online (Sandbox Code Playgroud)

因为List.map期望一个Function. 如果List.map需要 a PartialFunction,它会被翻译成这样:

swapped_list = list.map(
  new scala.PartialFunction2[Tuple2[Int, Int], Tuple2[Int, Int]] {
    def apply(x: Tuple2[Int, Int]): Tuple2[Int, Int] = x match {
      case (a, b) => new Tuple2[Int, Int](b, a) 
    }

    def isDefinedAt(x: Tuple2[Int, Int]): Boolean = x match {
      case (a, b) => true
      case _ => false
    }
  }
)
Run Code Online (Sandbox Code Playgroud)

我想知道这样做的目的case

这就是您编写模式匹配匿名函数的方式。的目的,case在这里是一样的目的"在字符串文本或的目的class类声明中,它只是写一局部函数的语法。

这背后是否有设计原则或什么?

不清楚你的意思。解析器需要某种方式来识别语言结构,关键字之类case的方法是实现这一目标的众多可能方法之一。

在一些类似的问题下,有人将其解释为偏函数的应用。

那是错误的。它不是apply,也不是函数。它正在定义一个函数List.map是在这种情况下应用该功能的那个。

但是,即使它们是对的,我们到底为什么还要使用偏函数呢?

为什么不?

以这种方式编写它允许您为元组的元素提供意图揭示的语义名称。a并且b可能不是最好的编程历史名字(我会打电话给他们first,并second代替),但他们肯定拍x._1x._2

IMO,写这个最自然的形式如下

swapped_list = list.map(x => (x._2, x._1))
Run Code Online (Sandbox Code Playgroud)

你的声明的重要部分是这样的:

海事组织

那是你的意见。显然,您发布的代码的作者有不同的意见。他们的意见和你的一样有效。

从对我从网上提取的几个不同代码片段的简短、完全不科学、有偏见、不具有代表性的调查来看,我的样本集几乎 100% 不同意你的意见,并且更愿意能够为元组元素提供揭示意图的语义名称。

事实上,在你编辑之前,你自己已经写过这样的:

IMO,写这个最自然的形式如下

swapped_list = list.map(x => (x._1, x._2))
Run Code Online (Sandbox Code Playgroud)

因此,您实际上在没有注意到的情况下交换了索引。这样做会更容易发现:

swapped_list = list.map { case (a, b) => (b, a) }
swapped_list = list.map { case (a, b) => (a, b) }
Run Code Online (Sandbox Code Playgroud)

甚至更好:

swapped_list = list.map { case (first, second) => (second, first) }
swapped_list = list.map { case (first, second) => (first, second) }
Run Code Online (Sandbox Code Playgroud)

当然,最好的写法是:

swapped_list = list.map(_.swap)
Run Code Online (Sandbox Code Playgroud)

使用scala.Tuple2.swap方法。