对Scala中的私有变量的公共只读访问

yeotifhr  于 2022-11-09  发布在  Scala
关注(0)|答案(1)|浏览(208)

序言:我正在教授一门关于使用Scala的对象函数式编程的课程,我们所做的一件事就是拿出示例问题,并比较如何使用对象函数式编程和使用基于状态的、面向对象的编程来实现它们,这是大多数学生的背景。

因此,我想在Scala中实现一个简单的类,它有一个private var和一个public访问器方法(这是基于状态的面向对象编程中的一种非常常见的用法)。看看Alvin Alexander的《Scala Cookbook》,推荐的代码相当可怕:

class Person(private var _age: Int): 
  def incrAge() = _age += 1
  def age = _age

我之所以说“可怕”,是因为我必须发明两个基本上表示age字段的名称,一个用在构造函数中,另一个用在类接口中。我很好奇更熟悉Scala的人是否知道可以避免这种情况的更简单的语法?

编辑:我现在很清楚,Scala将val/var声明与给定的可见性(public/private)结合在一起,因此对于var,访问器和赋值器都是public,或者两者都是private。根据不同的观点,您可能会发现这不灵活,或者觉得这是对您使用var🙂的惩罚。

jmp7cifd

jmp7cifd1#

是的,更好的方法是不使用var

class Person(val age: Int) {
   def incrAge = new Person(age+1)
}

如果要编写惯用的Scala代码,首先应该假装它的某些部分根本不存在:主要是varnullreturn,但也包括可变结构或集合、数组和某些方法,如TryOptionAwait对象上的.get。哦,还有isInstanceOfasInstance
你可能会问:“如果这些东西不应该被使用,为什么它们会存在?”嗯,因为有时,在极少数非常具体的情况下,它们实际上对实现一个非常有限、非常具体的目的是有用的。但这可能不到您职业生涯中遇到的案例的0.1%,除非您参与了一些核心的低级库开发(在这种情况下,您不会在这里发布这样的问题)。
所以,直到你掌握了足够的语言能力,能够明确地将这0.1%的案例与其他99.9%的案例区分开来,你最好忽略这些语言功能,假装它们不存在(如果你不能想出如何在不使用这些功能的情况下完成某项任务,在这里发布一个问题,人们会很乐意帮助你)。
你说过“不得不创建两个名字来管理一个字段是很难看的。”确实是这样。但你知道什么更丑吗?使用VAR。
(顺便说一句,在Java中通常使用getAgesetAge--仍然是两个名称。丑陋的根源在于允许用给定名称标记的值在程序执行的不同点上不同,而不是突变的语义看起来有多具体)。

相关问题