【问题标题】:private keyword has different meaning on class definitionprivate 关键字在类定义上有不同的含义
【发布时间】:2022-01-18 13:17:12
【问题描述】:

我认为我对 Scala 有很好的理解,直到我发现自己处于这个简单的场景中

sealed abstract case class Name private(name: String)

object Name {
    def make(name: String): Option[Name] =
      if (name.nonEmpty) Some(new Name(name) {}) else None
  }

我的问题是关于班级的 private 修饰符。 如果我像这样使用它,一切正常,但如果我在开头移动 private 关键字,就像

private sealed abstract case class Name(name: String) 它无法编译,因为给了我以下错误

私有类名称作为类型的一部分逃脱其定义范围 选项[example.package.Name]

example.package 是我正在使用的包对象。

我想我需要澄清一下,因为我不确定这里发生了什么

【问题讨论】:

  • 提示:什么前面的关键字是?
  • @JörgWMittag what 不是 scala 中的关键字,不知道你在说什么
  • Jörg 的意思是:关键字在哪里?前面是什么?这是给您的提示,以便您找到问题的答案。
  • 这能回答你的问题吗? Private and protected constructor in Scala

标签: scala


【解决方案1】:

sealed abstract case class Name(name: String)

Name 有效地表示两者

  • 类的名称
  • 该类的默认构造函数
sealed abstract case class Name private(name: String)

声明该类是公共的,但构造函数是私有的(即只能从该类或其伴生对象中调用)。

private sealed abstract case class Name(name: String)

声明该类是私有的(这意味着构造函数也是私有的)。

【讨论】:

  • 值得补充的是,您仍然可以在伴随对象之外创建case class private Name 的实例,因为case class 有一个自动public 构造函数。私有构造函数仅对裸 class 定义才真正有意义。
  • sealed abstract case class 带有 private 构造函数会抑制伴随对象中自动生成的公共 apply 方法。这是获得case class 语义的[有用子集] 的有用技巧,同时强制执行不变量而不抛出异常(例如,让apply 方法返回Option/Try/Either/Cats Validated/etc .).
  • 感谢您的澄清和对混淆的歉意。我说的是确实有这个问题的非抽象案例类,但在这个特殊案例中这显然不是问题。我已经适当地更新了自己的答案。
【解决方案2】:

此代码编译没有错误:

 private sealed abstract case class Name(name: String)

问题是您返回的值包含此类的public 值,因此定义泄漏了,它实际上不是private。您需要确保所有对Name 的引用也是private

第一个语法将构造函数标记为私有;

sealed abstract case class Name private(name: String)

这意味着只能从Name 伴随对象内部调用构造函数。所以这是不允许的

val name = new Name("name") // constructor Name in class Name cannot be accessed

【讨论】:

  • 这是不正确的。标记 case class abstract 会抑制伴随 apply(和 copy 方法)。
  • 虽然我所说的在技术上并不正确(因为我说的是case class 而不是abstract case class),但确实令人困惑,对此我深表歉意。我已将其从我的答案中删除,但我将其余答案留在这里,因为它解释了 OP 看到的错误,而另一个答案没有。
猜你喜欢
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多