我知道case class
会导致编译器使用样板扩展class
来实现某种有用的模式(“ plain and immutable data-holding objects that should exclusively depend on their constructor arguments”)。
但是在这种情况下,“案例”一词本身对我没有任何意义。我习惯将它用作C#中switch
语句的一部分,但这似乎与Scala使用该词无关。
当我可以将单词附加到特定含义时,我发现更容易编程。现在,我的心理模型是case => boilerplate
,就像它可能是blurg => boilerplate
一样。这是一种有效的思维模式,但是模棱两可使人们容易误解或完全忘记。
那么case
一词与编译器的实际作用有什么关系?
我不是在寻找“设计师的想法”,而是“在给定语言设计常识的情况下,将这个术语与其含义联系起来的一种合理方法”。
答案 0 :(得分:3)
我认为,术语case
来自case analysis,这是一种通过称为algebraic data types的特殊结构实现的推理技术。 case
中的case class
本身可能没有多大意义,但是当它构成sealed
结构的一部分时,例如Scala定义ADT的方式
sealed trait Number
case object Zero extends Number
case class Succ(v: Number) extends Number
然后我们看到构造Number
的两种形式,即使用Zero
和Succ
构造函数。因此,每当我们不得不考虑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如何使用class
,object
,trait
等术语,这些术语似乎来自于面向对象的范例,但是从概念上讲,ADT几乎没有与OO中的类层次结构相同。我个人觉得这很令人困惑,但是我们必须记住Scala既是功能语言又是OO语言,这可能是造成此类术语溢出的原因。在其他一些更“纯”的语言中,ADT的case class
仅用竖线|
表示,就像这样
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
我的建议是尽量不要成为“言语的奴隶”,而应该为你服务。重要的是单词或术语后面的含义,而不是单词本身。不要围绕术语构建思维模型,而应围绕它们为穿越沟通薄弱而努力奋斗的沉重概念构建思维模型。我认为case
正在尝试传达的概念是ADT。
答案 1 :(得分:-1)
C#具有android:launchMode="singleInstance"
/ switch
语言功能,该功能允许通过将输入与一组可能的值进行匹配来控制程序流。
case
在这里,public static GetEmail(string name)
{
switch (name)
{
case "bill":
return "bill@example.com";
case "jane":
return "jane@example.com";
default:
return null;
}
}
大致意味着“在给定值等于该值的情况下,执行X。”
Scala的case
/ match
功能类似于C#的功能。
case
但是它功能更强大。它旨在针对比字符串更复杂的事物评估“匹配”。要利用这一强大的匹配功能,您可以使用def getEmail(name: String): Option[String] = {
name match {
case "bill" => Option("bill@example.com")
case "jane" => Option("jane@example.com")
case _ => None
}
}
定义不可变的数据保存类。
这是一个简单但希望有帮助的案例类示例,它与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
。