Reputation: 2257
Initialy we have a code like
class Person(firstName: String, lastName: String)
val (firstName, lastName) = person
Somebody swaps fields
class Person(lastName: String, firstName: String)
val (firstName, lastName) = person
Compiler is happy!
Upvotes: 2
Views: 119
Reputation: 149558
The compiler has no way to know you swapped the order of the fields because the analysis doesn't look up the argument name. As long as the typer type checks, everything is fine. What you can do is an additional level of types:
case class FirstName(name: String)
case class LastName(name: String)
class Person(firstName: FirstName, lastName: LastName)
Now swapping the types will cause a compile time error.
If you don't want the additional overhead of allocationing additional objects, look into shapeless tagged types:
import shapeless.tag.@@
trait FirstNameTag
trait LastNameTag
type FirstName = String @@ FirstNameTag
type LastName = String @@ LastNameTag
case class Person(fn: FirstName, ln: LastName)
And now:
import shapeless.tag
val firstName: FirstName = tag[FirstNameTag][String]("yuv")
val lastName: LastName = tag[LastName][String]("itz")
val person = Person(firstName, lastName)
or as @Ren points out use value classes:
case class FirstName(name: String) extends AnyVal
case class LastName(name: String) extends AnyVal
Upvotes: 5