Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"stable identifier required" for an enumeration class

Tags:

scala

In the following code segment,

val line = ... // a list of String array 
line match {
  case Seq("Foo", ... ) => ...
  case Seq("Bar", ... ) => ...
  ...

I change the above code to the followings:

object Title extends Enumeration  {
  type Title = Value
  val Foo, Bar, ... = Value
}

val line = ... // a list of String array 
line match {
  case Seq(Title.Foo.toString, ... ) => ...
  case Seq(Title.Bar.toString, ... ) => ...
  ...

And, I get an error:

stable identifier required, but com.abc.domain.enums.Title.Foo.toString found.

What will be a right way to replace a string in the case statement?

like image 860
TeeKai Avatar asked Oct 25 '25 10:10

TeeKai


2 Answers

A function call cannot be used as a stable identifier pattern (that is it's not a stable identifier).

In particular:

A path is one of the following.

  • The empty path ε (which cannot be written explicitly in user programs).

  • C.this, where C references a class. The path this is taken as a shorthand for C.this where C is the name of the class directly enclosing the reference.

  • p.x where p is a path and x is a stable member of p. Stable members are packages or members introduced by object definitions or by value definitions of non-volatile types.

  • C.super.x or C.super[M].x where C references a class and x references a stable member of the super class or designated parent class M of C. The prefix super is taken as a shorthand for C.super where C is the name of the class directly enclosing the reference.

A stable identifier is a path which ends in an identifier.

Thus, You cannot use a function call like xyz.toString in a pattern.

To make it stable you can assign it to a val. If the identifier starts with a lower case letter, you will need to enclose it in backticks (`) to avoid shadowing it:

 val line = Seq("Foo") // a list of String array
 val FooString = Title.Foo.toString
 val fooLowerCase = Title.Foo.toString

 line match {
   case Seq(FooString) => ???
   // case Seq(fooLowerCase) (no backticks) matches any sequence of 1 element, 
   // assigning it to the "fooLowerCase" identifier local to the case
   case Seq(`fooLowerCase`) => ???
 }

You can use guards though:

line match {
  case Seq(x) if x == Title.Foo.toString => ???
}
like image 102
Giovanni Caporaletti Avatar answered Oct 28 '25 04:10

Giovanni Caporaletti


toString is a function and functions cannot be used for pattern matching.

I think Enumeration is probably not what you are looking for.

To match a string you could

object Title {
  val Foo = "Foo"
  val Bar = "Bar"
}

line match {
  case Seq(Title.Foo, ...) => ???
}
like image 33
Sascha Kolberg Avatar answered Oct 28 '25 03:10

Sascha Kolberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!