赋予以下功能:
def prefixDr(firstName: String, lastName: String): String =
"Dr. " + firstName + " " + lastName
假设我决定添加Value Class以避免混淆名字和姓氏,例如:
scala> prefixDr("Doe", "Jane")
res5: String = Dr. Doe Jane // whoops - should've been in reverse order
class FirstName(val value: String) extends AnyVal
class LastName(val value: String) extends AnyVal
然后使用它们:
def prefixDr(firstName: FirstName, lastName: LastName): String =
"Dr. " + firstName.value + " " + lastName.value
现在比以前更安全:
scala> prefixDr( new FirstName("Jane"), new LastName("Doe") )
res6: String = Dr. Jane Doe
首先,我对值类型的动机的理解是避免堆分配,即将值存储在堆栈上,而不是堆上;前者的访问时间比后者快。
但是,在上述情况下,据我所知,我正在使用两种
String
,它们是AnyRef
的子类型,即java.lang.Object
,它们分配给堆。因此,在上面的示例中,即使用2个值类,与
case class
相比使用它们有什么好处? 最佳答案
值类并不意味着提供一种进行堆栈分配而不是堆分配的方法。通常,这是您无法控制的。相反,它们旨在防止在另外创建“包装”类时发生额外的对象分配。
就Firstname
而言,扩展AnyVal
意味着当您执行类似操作时
val x = new Firstname("Bob")
实际上没有创建
FirstName
的实例,并且x
实际上只是运行时的String
(假设您不执行文档描述的会强制分配的操作之一,例如模式匹配)。但是AnyVal
绝对不会改变包装的String
的分配方式。关于scala - 带有字符串内部类型的值类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41786690/