免责声明:我在Java方面比在Scala(我正在学习)方面经验丰富得多。
在Java中,我已多次阅读过切换可能对面向对象有害,尤其是在对类型使用时(这种问题也会导致这种情况:http://www.antiifcampaign.com/)。
在Scala中,Martin Odersky的介绍视频课程之一展示了模式匹配如何更好地替代多个"低级" isInstanceOf
检查。
尽管模式匹配比简单的Java交换机捕获更灵活的模式,但我仍然认为第一个是后者的概括。
不要模式匹配和"打开类型"大致分享相同的基本方法?
是不是模式匹配了一些隐藏大量isInstanceOf
/ asInstanceOf
的句法糖?
如果没有,模式匹配将如何更灵活(如:对变化具有弹性),而不是自己编写那些低级别的检查(除了这项繁琐任务的容易出错的性质)?
答案 0 :(得分:6)
在某些意义上,模式匹配很可能是“语法糖”,但它不仅仅是代码替换。
a)match
结构将通过确保没有未发现的案例来强制域的完整性,除非您明确指出它只是部分功能。
b)匹配语法不那么详细。
c)匹配构造包括守卫,符合比赛资格的谓词。
def mergeSort(a: List[Int], b: List[Int]): List[Int] = (a, b) match {
case (ah :: at, bh :: bt) if ah < bh =>
ah :: mergeSort(at, b)
case (ah :: at, bh :: bt) if ah >= bh =>
bh :: mergeSort(a, bt)
case (Nil, b) =>
b
case (a, Nil) =>
a
}
d)解构
...
case Node(x, Empty, Empty) =>
x - 52
...
声明形式更容易阅读(给出一点经验)。
编辑:术语&#34;句法糖&#34;经常使用Scala。但是,类型推理和&#34;积极的&#34;模式匹配中使用的类型分辨率可用于强大的语言结构。至于原始问题,模式匹配独立于面向对象,并提供了强大的,类型安全的方法来访问数据,这可能使类的使用不那么需要。
答案 1 :(得分:5)
如果你有n种类型的名词有m种类型的动词,你有n x m个名词 - 动词组合来跟踪。
管理这种复杂性有两种很好的策略。
您可以按名词(类)组织代码,每个类都需要能够处理每个动词(方法)。这样可以轻松添加新名词。当然,当你添加一个新动词时,通过每个你的名词并确保它可以处理新动词是很烦人的。这是面向对象的方法。
您还可以通过动词(函数)组织代码,每个函数都需要能够处理每个名词(模式)。这样可以很容易地添加新动词。当然,当你添加一个新名词时,通过每个动词并确保它可以处理新名词很烦人。这是功能性方法。
这两种方法都没有明显改善,两者都得到了很好的使用。但是,当您尝试混合它们时,可能会遇到问题,因此通常您希望非常清楚针对给定问题使用哪种方法。
答案 2 :(得分:1)
在Scala中,模式匹配是通过提取器完成的。提取器本身就是对象,只能访问与模式匹配的对象的公共API。
因此,模式匹配不会破坏对象封装。
理论上,所有条件(包括模式匹配)都可以用多态来代替。请参阅Smalltalk作为一种语言示例,该语言没有条件,没有循环,没有开关,除了多态消息调度之外没有任何类型的控制结构。并将Newspeak视为Smalltalk灵感语言的一个例子,该语言具有强大的模式匹配功能,灵感来自Scala和F#,它完全基于多态消息发送实现为库。
当这样做时,模式匹配就像面向对象一样。