繁体   English   中英

Scala的“案例类”中的“案例”一词是什么意思?

[英]What is the meaning of the word “case” in scala's “case class”?

我知道case class会导致编译器增加一个带有样板的class ,以实现某种有用的模式(“ 纯且不可变的数据保存对象应完全依赖于其构造函数参数 ”)。

但是在这种情况下,“案例”一词本身对我没有任何意义。 我习惯于将它用作C#中switch语句的一部分,但这似乎与Scala对该词的使用无关。

当我可以将单词附加到特定含义时,我发现更容易编程。 现在我的思维模型是case => boilerplate ,就像blurg => boilerplate 这是一种可行的思维模式,但是模棱两可让人们容易误解或完全忘记。

那么, case一词与编译器实际做什么有什么关系?

我不是在寻找“设计师的想法”,而是在给定语言设计常识的前提下,“将这个术语与其含义联系起来的一种合理方法”。

在我看来,“ case一词来自案例分析 ,这是一种通过称为代数数据类型的特殊结构实现的推理技术。 case case class本身可能没有多大意义,但是当它构成sealed结构的一部分时,例如,Scala就是这样定义ADT的

sealed trait Number
case object Zero extends Number
case class Succ(v: Number) extends Number

然后我们看到有两种构造Number形式 ,即使用ZeroSucc 构造函数 因此,无论何时我们必须考虑Number ,我们至少知道要考虑两种不同的case 例如,假设我们要在Number上定义加法,那么其定义将必须处理两种情况,例如

def sum(a: Number, b: Number): Number =
  a match {
    case Zero => b
    case Succ(v) => Succ(sum(v, b))
  }

哪里

sum(Succ(Zero), Succ(Zero)) == Succ(Succ(Zero)) // 1 + 1 = 2
sum(Succ(Succ(Zero)), Succ(Zero)) == Succ(Succ(Succ(Zero))) // 2 + 1 = 3
sum(Succ(Zero), Succ(Succ(Zero))) == Succ(Succ(Succ(Zero))) // 1 + 2 = 3
sum(Zero, Succ(Succ(Zero))) == Succ(Succ(Zero)) // 0 + 2 = 2
sum(Succ(Succ(Zero)), Zero) == Succ(Succ(Zero)) // 2 + 0 = 2

请注意,为了定义ADT,Scala如何使用classobjecttrait等术语,这些术语似乎来自于面向对象的范例,但是ADT从概念上讲与OO中的类层次结构几乎没有共通之处。 我个人觉得这很令人困惑,但是我们必须记住Scala既是功能语言又是OO语言,这可能是造成此类术语溢出的原因。 在其他一些“纯”语言中,ADT的case class仅由竖线表示| ,像这样说

Inductive nat : Type :=
   | O : nat
   | S : nat -> nat.

我的建议是尽量不要成为“言语的奴隶”,而是言语应该为您服务。 重要的是单词或术语背后的含义 ,而不是单词本身。 不要围绕术语构建思维模型,而应围绕它们为穿越沟通薄弱而努力奋斗的沉重概念构建思维模型。 我认为,正在尝试进行通信的概念case是ADT。

C#具有switch / case语言功能,该功能允许通过将输入与一组可能的值进行匹配来控制程序流程。

public static GetEmail(string name)
{
  switch (name)
  {
    case "bill":
      return "bill@example.com";
    case "jane":
      return "jane@example.com";
    default:
      return null;
  }
}

在此, case大致是指“在给定值等于该值的情况下,执行X”。

Scala的match / case功能类似于C#的功能。

def getEmail(name: String): Option[String] = {
  name match {
    case "bill" => Option("bill@example.com")
    case "jane" => Option("jane@example.com")
    case _ => None
  }
}

但这要强大得多。 它旨在针对比字符串更复杂的事物评估“匹配”。 要利用此强大的匹配功能,您可以使用case class定义不可变的数据保存case class

这是一个简单但希望有用的案例类示例及其与match / case

case class Person(name: String, hasEmail: Boolean)

object EmailHelper {
  def getEmail(person: Person): Option[String] = {
    person match {
      case Person(_, false) => None
      case Person("bill", true) => Option("bill@example.com")
      case Person("jane", true) => Option("jane@example.com")
      case _ => None
    }
  }
}

简而言之, case class强制执行一组约束,这些约束使该类可与match / case

暂无
暂无

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

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