Are there any advantages to using a value class (without methods) and a type alias?

Say I have this ADT:

case class Person(id: String)
case class Kid(id: String, name: String)

I would like to present the id field as a more explicit and safe type. I have two options

1. alias type

type PersonId = String
case class Person(id: PersonId)
case class Kid(id: String, name: PersonId)

2. value class

case class PersonId(id: String) extends AnyVal
case class Person(id: PersonId)
case class Kid(id: String, name: PersonId)

Which approach is more idiomatic? Are there any advantages to using a value class in this case (without additional methods)?

+4
source share
3 answers

Typical aliases are purely syntactic convenience - in some cases they can make the code cleaner or easier to refactor, but they provide no additional type security. For example, suppose I have code like this:

type DegreesC = Double
type DegreesF = Double

def c2f(c: DegreesC): DegreesF = (c * 9.0 / 5.0) + 32

, :

val currentTempInF = 62.0

c2f:

scala> c2f(currentTempInF)
res1: DegreesF = 143.6

case ( ):

case class DegreesC(value: Double) extends AnyVal
case class DegreesF(value: Double) extends AnyVal

def c2f(c: DegreesC): DegreesF = DegreesF((c.value * 9.0 / 5.0) + 32)

val currentTempInF = DegreesF(62.0)

:

scala> c2f(currentTempInF)
<console>:14: error: type mismatch;
 found   : DegreesF
 required: DegreesC
       c2f(currentTempInF)
           ^

, . , Scala , , , , , . , ( - ).

+3

( ). . PersonId ,

type PersonId = String

case Kid . PersonId

 case class PersonId(id: String) extends AnyVal

Kid PersonId , , , PersonId.

AnyVal case , . .

+2

, .

type PersonId = String
case class Person(id: PersonId)

Person("some random string")

case class PersonId(id: String) extends AnyVal
case class Person(id: PersonId)

Person("some random string")

0

Source: https://habr.com/ru/post/1669733/


All Articles