Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an enum in scala that has an extra field

Tags:

enums

scala

In Java I have something like this

public enum FlatFileHeaderMapping {

   HEADER_EL(1),
   HEADER_RESERVED1(5),
   HEADER_RESERVED2(2),
   HEADER_MESSAGE_TYPE(4)

   public final int fieldSize;

    private FlatFileHeaderMapping(int fieldSize) {
        this.fieldSize = fieldSize;
   }

}

which I can then use it place each line into a map and later access the keys in the map via this enum (like symbols)

Enumeration does not have this quality as far as I can see, and case classes are not ordered like the enum declarations - so cannot be used to match a record layout as shown above. At least not without the support of an ordered collection.

I could be missing something obvious, hence the question!

Thanks

Ray

like image 857
Mond Raymond Avatar asked Jun 24 '11 20:06

Mond Raymond


2 Answers

overthink is right, but there's a less verbose way of declaring the case objects:

sealed abstract class FlatFileHeaderMapping(val fieldSize: Int)
case object HEADER_EL extends FlatFileHeaderMapping(1)
case object HEADER_RESERVED1 extends FlatFileHeaderMapping(5)
case object HEADER_RESERVED2 extends FlatFileHeaderMapping(2)
case object HEADER_MESSAGE_TYPE extends FlatFileHeaderMapping(4)
like image 107
prat_c Avatar answered Oct 18 '22 17:10

prat_c


You could try using case objects:

sealed trait FlatFileHeaderMapping { val fieldSize: Int }                                                                                                                                                                          
case object HEADER_EL extends FlatFileHeaderMapping { val fieldSize = 1 }                                                                                                  
case object HEADER_RESERVED1 extends FlatFileHeaderMapping { val fieldSize = 5 }                                                                                           
case object HEADER_RESERVED2 extends FlatFileHeaderMapping { val fieldSize = 2 }                                                                                           
case object HEADER_MESSAGE_TYPE extends FlatFileHeaderMapping { val fieldSize = 4 } 

You can then use the enum like so:

object Test {                                                                                                                                                              
  def foo(x: FlatFileHeaderMapping) {                                                                                                                                      
    val result =                                                                                                                                                           
      x match {
        case HEADER_EL => "it's a HEADER_EL!"                                                                                                                              
        case other => "its field size is: " + other.fieldSize                                                                                                             
      }                                                                                                                                                                    
    println(result)                                                                                                                                                        
  }                                                                                                                                                                        

  def main(args: Array[String]) {                                                                                                                                          
    foo(HEADER_EL)                                                                                                                                                         
    foo(HEADER_MESSAGE_TYPE)                                                                                                                                               
  }                                                                                                                                                                        
}

The main nicety you get here is compile-time checking that all enum values are handled. i.e in the x match { ... } code above you'd get a compile error if you didn't have the 'case other => ...` clause in there.

I'm pretty much just restating this answer, which lists pros and cons of this approach.

like image 20
overthink Avatar answered Oct 18 '22 16:10

overthink