Romper
Romper

Reputation: 2257

Can destructuring cause bugs in future?

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

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

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

Related Questions