I think I had a good understanding of Scala till I find myself in this simple scenario
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
}
my question is about the private
modifier for the class.
If I use it like this, everything works, but if I move the private
keyword at the start, something like
private sealed abstract case class Name(name: String)
it doesn't compile becuase gives me the following error
private class Name escapes its defining scope as part of type Option[example.package.Name]
where example.package
is the package object I'm working in.
I think I need some clarification because I'm not sure what's happening here
CodePudding user response:
In
sealed abstract case class Name(name: String)
Name
effectively denotes both
- the name of the class
- the default constructor for that class
sealed abstract case class Name private(name: String)
declares that the class is public, but the constructor is private (i.e. can only be called from within that class or its companion object).
private sealed abstract case class Name(name: String)
declares that the class is private (which implies that the constructor is also private).
CodePudding user response:
This code compiles with no error:
private sealed abstract case class Name(name: String)
The problem is that you are then returning a value that contains a public
value of this class, so the definition is leaking out and it isn't really private
. You need to make sure that all references to Name
are also private
.
The first syntax marks the constructor as private;
sealed abstract case class Name private(name: String)
This means that the constructor can only be called from inside the Name
companion object. So this is not allowed
val name = new Name("name") // constructor Name in class Name cannot be accessed