gpt4 book ai didi

scala - 声明 Scala 案例类有哪些缺点?

转载 作者:行者123 更新时间:2023-12-03 04:48:07 25 4
gpt4 key购买 nike

如果您正在编写使用大量漂亮、不可变数据结构的代码,则案例类似乎是天赐之物,只需一个关键字即可免费为您提供以下所有功能:

  • 默认情况下一切都是不可变的
  • 自动定义 setter/getter
  • 不错的 toString() 实现
  • 兼容 equals() 和 hashCode()
  • 具有 unapply() 方法的伴生对象用于匹配

但是将不可变数据结构定义为案例类有哪些缺点?

它对类(class)或其客户有什么限制?

在某些情况下您应该更喜欢非案例类吗?

最佳答案

首先是好的方面:

默认情况下一切都是不可变的

是的,如果需要的话甚至可以覆盖(使用var)

自动定义 setter/getter

可以在任何类中通过在参数前加上val

不错的toString()实现

是的,非常有用,但如果需要,可以在任何类(class)上手动完成

兼容equals()hashCode()

结合简单的模式匹配,这是人们使用案例类的主要原因

具有用于匹配的 unapply() 方法的伴随对象

也可以使用提取器在任何类上手动完成

这个列表还应该包括 super 强大的复制方法,这是 Scala 2.8 中最好的东西之一

<小时/>

坏处是,案例类只有少数真正的限制:

您无法使用与编译器生成的方法相同的签名在伴生对象中定义 apply

但在实践中,这很少是一个问题。更改生成的 apply 方法的行为肯定会让用户感到惊讶,并且强烈建议不要这样做,这样做的唯一理由是验证输入参数 - 最好在主构造函数主体中完成这项任务(这也使得在使用 时可以进行验证>复制)

你不能子类化

确实如此,尽管案例类本身仍然有可能是后代。一种常见的模式是构建特征的类层次结构,使用案例类作为树的叶节点。

还值得注意的是 sealed 修饰符。具有此修饰符的特征的任何子类必须在同一文件中声明。当对特征的实例进行模式匹配时,如果您没有检查所有可能的具体子类,编译器可以警告您。当与案例类结合使用时,如果代码在没有警告的情况下编译,这可以为您提供非常高水平的信心。

作为 Product 的子类,案例类的参数不能超过 22 个

没有真正的解决方法,除了停止滥用具有这么多参数的类:)

还有...

有时会注意到的另一个限制是 Scala(当前)不支持惰性参数(如 lazy val,但作为参数)。解决方法是使用按名称参数并将其分配给构造函数中的惰性 val。不幸的是,按名称参数不会与模式匹配混合,这会阻止该技术与案例类一起使用,因为它会破坏编译器生成的提取器。

如果您想要实现功能强大的惰性数据结构,这一点是相关的,并且有望通过在 Scala 的 future 版本中添加惰性参数来解决。

关于scala - 声明 Scala 案例类有哪些缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4653424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com