【问题标题】:Public read-only access to a private var in Scala对 Scala 中的私有变量的公共只读访问
【发布时间】:2022-09-24 03:31:08
【问题描述】:

我想在 Scala 中创建一个 Person 类,它有一个私有 var 字段来存储人的年龄,并允许对该字段进行公共读取访问。查看 Alvin Alexander 的“Scala Cookbook”,执行此操作的代码非常可怕:

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

必须创建 _name 是人为的,并且从接口中并不清楚这个构造函数参数本质上与 age 访问器相同。这样做有没有更好的办法?

  • \"这样做有没有更好的办法?\"除了不使用vars 而是使用不可变的案例类之外,不,我想不出\“更好的方法\”.主要是因为我不明白这有什么问题?
  • 必须创建两个名称来管理单个字段是丑陋的。 age 访问器给人的印象是该字段被称为 age,但如果在构造函数中使用 pass-by-name,客户端必须记住使用 _age。这不会发生在例如Java 或 Ruby。我不能使用案例类,因为我想要具有标识的正确对象。
  • \"这不会发生在例如 Java 或 Ruby 中。\"当然会(至少在爪哇),实际上更糟糕的是,您需要age 属性、getAge 方法和构造函数的name 参数,并且您需要执行this.age = age 来实现相同的行为,您可以使用age in斯卡拉只需将 getter 命名为 getAge。 -\"我不能使用案例类,因为我想要具有标识的正确对象\"不知道正确的对象意味着什么,如果您需要使用引用相等,您可以随时使用eq,但这通常是一个坏主意或不必要的。
  • 确切地。在 Java 中,尽管存在缺陷,但字段 age 可以与用于初始化它的构造函数参数具有相同的名称。我觉得奇怪的是 Scala 没有更优雅地处理这种常见情况。顺便说一句,这解释了对象身份:scala-exercises.org/scala_tutorial/classes_vs_case_classes。
  • 无论如何,你可以用更多的样板得到你想要的:scastie.scala-lang.org/BalmungSan/qmBOURkQQuaEmmgPPhdOtg/1

标签: scala constructor


【解决方案1】:

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

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

如果你要编写惯用的 scala 代码,你应该先假装它的某些部分根本不存在:主要是 vars、nulls 和 returns,但也包括可变结构或集合、数组、以及 .get 或 Try 或 Option 或 Await 对象上的某些方法。哦,还有isInstanceOf 和asInstance。

您可能会问“如果这些东西不应该被使用,为什么还要存在这些东西?”。嗯,因为有时,在极少数非常具体的情况下,它们实际上对于实现非常有限的非常具体的目的很有用。但这可能不到你职业生涯中遇到的案例的 0.1%,除非你参与了一些硬代码低级库开发(在这种情况下,你不会在这里发布这样的问题)。

所以,除非你掌握了足够的语言能力,能够明确区分这 0.1% 的案例和其他 99.9% 的案例,否则你最好忽略这些语言特征,并假装它们不存在(如果你可以的话)不知道如何在不使用其中之一的情况下完成某项任务,请在此处发布问题,人们会很乐意帮助您)。

你说“必须创建两个名称来管理一个字段是丑陋的。”的确。但你知道什么更丑吗?使用变量。

(顺便说一句,您通常在 java 中执行此操作的方式是 getAge 和 setAge - 仍然是两个名称。丑陋的根源在于允许使用给定名称标记的值在程序执行的不同点不同,而不是如何特别是突变的语义看起来像)。

【讨论】:

  • 感谢你的回答。我一直是全职软件专业人士 30 多年,博士等,所以不寻求新手建议。 Scala 声称支持 OOP,但我很困惑,表达一个简单的 OOP 习语需要创建一个人为的名称,并假设我一定遗漏了一些东西。似乎没有。答案可能是您的答案背后的原因,即 Scala 只是不太支持 OOP 习语,这让我很惊讶。
  • 你的学位和职业长度无关紧要。你显然是scala的新手。你不需要为此辩护。无论您以前获得多少文凭,获得新技能都没有错。 Scala 确实支持 OOP:您可以实现继承、封装,尤其是非常强大其中的多态性。您需要意识到的是,OOP 不是 Java 的同义词。 Java 只是可能的实现之一,而且在这方面很差。对于您的“博士等”,您必须知道 OOP 有某些特征,而可变性不是其中之一。
  • 我希望您至少尝试适当地回答我的问题,而不是发表诸如“OOP 不是 Java 的同义词”之类的空洞言论。
  • @ComDubh 相信我,您在其他领域的学位和经验,尽管如此,“避免 vars”是您可以得到的最合适的答案。此外,如果您要编写 cmets 认真地暗示 OOP 意味着可变性,那么请准备好获得答案,其中我的“非 Java 同义词”评论是最具建设性的评论之一。 :)
猜你喜欢
  • 2011-07-22
  • 2012-12-28
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 2014-04-05
  • 2016-01-09
  • 1970-01-01
相关资源
最近更新 更多