Case Classes with optional fields in Scala

前端 未结 3 478
渐次进展
渐次进展 2020-12-15 04:15

For example, I have this case class:

case class Student (firstName : String, lastName : String)

If I use this case class, is it possible th

相关标签:
3条回答
  • 2020-12-15 04:45

    You were close:

    case class Student (firstName : String = "John", lastName : String = "Doe")
    
    val student = Student(firstName = "Foo")
    

    Another possibility is partially applied function:

    case class Student (firstName : String, lastName : String)
    
    val someJohn = Student("John", _: String)
    //someJohn: String => Student = <function1>
    
    val johnDoe = someJohn("Doe")
    //johnDoe: Student = Student(John,Doe)
    

    And to be complete, you can create some default object and then change some field:

    val johnDeere = johnDoe.copy(lastName="Deere")
    //johnDeer: Student = Student(John,Deere)
    
    0 讨论(0)
  • 2020-12-15 04:46

    I would see two ways this is normally done.

    1. default parameters

    case class Student (firstName : String, lastName : String = "")
    
    Student("jeypijeypi")   # Student(jeypijeypi,)
    

    2. alternative constructors

    case class Student (firstName : String, lastName : String)
    
    object Student {
        def apply(firstName: String) = new Student(firstName,"")
    }
    
    Student("jeypijeypi")   # Student(jeypijeypi,)
    

    Which one is better depends slightly on the circumstances. The latter gives you more freedom: you can make any parameter(s) optional, or even change their order (not recommended). Default parameters need always to be at the end of the parameter list, I think. You can also combine these two ways.

    Note: within the alternative constructors you need new to point the compiler to the actual constructor. Normally new is not used with case classes.

    0 讨论(0)
  • 2020-12-15 04:59

    If you just want to miss the second parameter without a default information, I suggest you to use an Option.

    case class Student(firstName: String, lastName: Option[String] = None)
    

    Now you might create instances this way:

    Student("Foo")
    Student("Foo", None)            // equal to the one above
    Student("Foo", Some("Bar"))     // neccesary to add a lastName
    

    To make it usable as you wanted it, I will add an implicit:

    object Student {
      implicit def string2Option(s: String) = Some(s)
    }
    

    Now you are able to call it those ways:

    import Student._
    
    Student("Foo")
    Student("Foo", None)
    Student("Foo", Some("Bar"))
    Student("Foo", "Bar")
    
    0 讨论(0)
提交回复
热议问题