如何在 Scala 中实现功能完备的不可变 类?
How to make fully functional immutable classes in Scala?
我注意到 Scala 有大小写 类。这些似乎是用于模式匹配的,但我喜欢我可以用它们来做到这一点:
val bankAccount1 = new BankAccount("Daniel", 100)
val bankAccount2 = bankAccount1.copy(funds = 200)
现在 "Daniel" 有两个银行账户,一个有 100 美元,一个有 200 美元。但是当事情变得更复杂时,BankAccount
需要被子类化,这不起作用,因为 case 类 不能扩展其他 case 类。
我想要不可变的 类 比可以扩展成更不可变的 类。就像我希望能够扩展 BankAccount
以具有不可变的子 类 SavingsBankAccount
和 CheckingBankAccount
。我不确定此时我是否需要 extend/implement Clonable
接口或定义自定义复制方法或类似的东西。我不想在 类.
中放置太多样板文件
(如果可能的话),我如何在 Scala 中制作不可变的 类,它可以被复制和子类化,并且不会过于混乱或冗长?
我认为在 Scala 中执行此操作的惯用方法是使用封装而不是继承。例如你可以有:
case class BankAccount(id: AccountId, customer: Customer)
case class SavingsBankAccount(account: BankAccount, line: SavingsLine)
这样您将保持不变性和自动应用、取消应用、equals、hashCode 和复制方法生成的良好特性。
但是,如果您真的想使用继承,您别无选择,只能推出您自己的自定义解决方案。例如实现一个特性SubclassableCaseClass
,它实现了帮助方法以快速定义方法案例类免费给你。
想想你的 BankAccount
是否真的需要具体。
我可以拥有一个不是储蓄或支票类型的银行账户吗?
如果这个问题的答案是否定的(在这个例子中我猜是),你可以使用摘要 class 或...
特质 !
http://www.scala-lang.org/old/node/126
当你真的不需要层次结构时,你可以用特征做很多事情。实际上 traits 比抽象的 classes 更好,因为你可以具有可组合性。
我发现在 scala 中编程大多数时候不需要扩展具体对象,特别是 class 只是打包数据的对象。
如果您确实需要 BankAccount
来具体说明,我猜您只剩下您已经建议的内容了。 :(
我注意到 Scala 有大小写 类。这些似乎是用于模式匹配的,但我喜欢我可以用它们来做到这一点:
val bankAccount1 = new BankAccount("Daniel", 100)
val bankAccount2 = bankAccount1.copy(funds = 200)
现在 "Daniel" 有两个银行账户,一个有 100 美元,一个有 200 美元。但是当事情变得更复杂时,BankAccount
需要被子类化,这不起作用,因为 case 类 不能扩展其他 case 类。
我想要不可变的 类 比可以扩展成更不可变的 类。就像我希望能够扩展 BankAccount
以具有不可变的子 类 SavingsBankAccount
和 CheckingBankAccount
。我不确定此时我是否需要 extend/implement Clonable
接口或定义自定义复制方法或类似的东西。我不想在 类.
(如果可能的话),我如何在 Scala 中制作不可变的 类,它可以被复制和子类化,并且不会过于混乱或冗长?
我认为在 Scala 中执行此操作的惯用方法是使用封装而不是继承。例如你可以有:
case class BankAccount(id: AccountId, customer: Customer)
case class SavingsBankAccount(account: BankAccount, line: SavingsLine)
这样您将保持不变性和自动应用、取消应用、equals、hashCode 和复制方法生成的良好特性。
但是,如果您真的想使用继承,您别无选择,只能推出您自己的自定义解决方案。例如实现一个特性SubclassableCaseClass
,它实现了帮助方法以快速定义方法案例类免费给你。
想想你的 BankAccount
是否真的需要具体。
我可以拥有一个不是储蓄或支票类型的银行账户吗?
如果这个问题的答案是否定的(在这个例子中我猜是),你可以使用摘要 class 或...
特质 !
http://www.scala-lang.org/old/node/126
当你真的不需要层次结构时,你可以用特征做很多事情。实际上 traits 比抽象的 classes 更好,因为你可以具有可组合性。
我发现在 scala 中编程大多数时候不需要扩展具体对象,特别是 class 只是打包数据的对象。
如果您确实需要 BankAccount
来具体说明,我猜您只剩下您已经建议的内容了。 :(