Scala 2.11中的类型化基元

mat*_*ter 3 scala

正如我所见,原始类型喜欢StringLong不能被扩展,因为它们被定义为final.但这对于类型安全的方法来说是一种遗憾.在围绕例如字符串操作的代码中,我更喜欢键入我的数据而不是使用String,Long,Int等:只要我使用类型安全的语言,我就希望我的代码真的可以输入从头开始.

根据实验和非常古老的问题类型证明,别名似乎不利于此.目前,我将使用以下内容:

case class DomainType(value: String)
Run Code Online (Sandbox Code Playgroud)

代价是必须使用.value需要价值的地方.

在scala 2.8之后是否还引入了其他语言功能,它可以巧妙地促进类型安全的子类型原语?是否存在代理基础值的任何对象覆盖,但仍然会发生类型匹配?

Lom*_*ard 6

我不同意你的思维方式.Java原语无法扩展,因为它们是原语(顺便说一句String不是原语).它们是字节代码类型的直接表示.从编译器的角度来看,扩展它们是没有意义的.

隐含价值类

Scala使用pimp我的库模式来处理这个问题,例如使用类RichInt.这允许在没有对象实例化(通过值类和隐含)的情况下(主要)向现有类型添加新方法.请同时查看隐式类.

implicit class DomainType(val o: String) extends AnyVal {
  def myDomainMethod: Int = o.size
}

"hello".myDomainMethod // return 5
Run Code Online (Sandbox Code Playgroud)

问题,这不允许你像你想要的那样限制一个类型DomainType.但是类型类可以帮助你.

输入类

这里我们要为类型添加约束,而不继承.正如在这个链接中所说,

因此,类型类允许ad-hoc和追溯多态.依赖于类型类的代码可以扩展而不需要创建适配器对象.

以下示例显示了该方法如何foo仅接受隐式类型DomainType[T]在范围内的参数.它取代了追溯多态性所需的继承.您还可以保留域类型的好处:意图很明确,呼叫类型安全,您可以添加新的域方法.

trait DomainType[T] {
  def myDomainMethod(o: T): Int
}

object DomainType {
  implicit object StringDomainType extends DomainType[String] {
    def myDomainMethod(o: String): Int = o.size
  }
}

def foo[T : DomainType](p: T): Int = {
  implicitly[DomainType[T]].myDomainMethod(p)
}

foo("hello") // return 5
foo(5) // compilation exception
Run Code Online (Sandbox Code Playgroud)

案例类+隐含

如果您的DomainType案例类唯一令您烦恼的是调用.value,您可以随时添加一个隐含的函数.

implicit def unwrapDomainType(o: DomainType): String = o.value
Run Code Online (Sandbox Code Playgroud)

当然,这会降低代码的清晰度,我不会推荐它.