类型类的使用以及类型类和类型特征之间的区别

时间:2016-11-02 12:11:50

标签: scala class types

两个问题

问题1 采用类型参数

的类有什么用?

我能理解

的用处
trait SomeTrait[T]

我正在努力理解可能是

之类的用例
class SomeClass[A](a:A) {...}

当我们将已知类型的参数传递给函数或类时,我们知道该参数允许哪些操作。所以,如果我有一个类如下,我知道因为参数是Int类型,我可以对参数'a'执行'+'

scala> class IntTest(a:Int) {
     | def plusandPrintInt = {println(a+1)} //as 'a' is Int, we can do +
     | }
defined class IntTest

scala> val i = new IntTest(1).plusandPrintInt
2
i: Unit = ()

但是当我创建一个接受类型参数[A]的类时,参数可以是任何类型。因此,我不会对传递的参数

进行什么操作
scala> class TypeClass [A](a:A) {
     | // what possibly can be done on A without knowing what A is?
     | }
defined class TypeClass

特征是不同的,因为我们没有在特征中实现函数,而是让其他类这样做。当扩展接受Type参数的Trait时,通常通过指定实参数类型来扩展它。因此,我们可以调用参数的特定操作,因为我们知道参数的类型是什么

scala> trait TraitClass [T] {
     | def whatever (t:T) // I am not bothered as I do not need to implement this function
     | }
defined trait TraitClass

scala> class extendTraitClass extends TraitClass[Int] {
     | def whatever(t:Int) {println(t+1)} //I know that t is Int so I can use +
     | }
defined class extendTraitClass

scala> (new extendTraitClass).whatever(1)
2

似乎“a”可用的唯一操作如下:

scala> def someFunction[A](a:A) {
     | a.   //double tabbed to get this list
!=   +    ==             ensuring   formatted   hashCode       toString
##   ->   asInstanceOf   equals     getClass    isInstanceOf   ?

问题2 类型类是否与类型特征相同?

2 个答案:

答案 0 :(得分:1)

  

采用类型参数

的类有什么用?

当您可以抽象类型参数时,多态类很有用。这意味着您的类所暴露的操作并不特定于某些具体类型。

采用非常常见的集合案例。例如,如果我们查看List[A],是否应为列表应包含的每种类型创建List[A]?当然不是,因为可以为任何类型的执行基础操作

Scala的另一个好例子是Option[A]。如果您是实施者,是否要为每个可能存在的值创建一个选项?即:

class IntOption(a: Int)
class StringOption(a: String)

你不希望这样,因为没有理由。由于我们可以对任何类型参数A进行抽象,因此可以使类或特征成为通用的,这样诸如map之类的操作可以采用那些抽象类型的更高阶函数。

  

类型类是否与类型特征相同?

不确定你的意思是“相同”。阶级和特征在性质上是不同的,具有不同的品质。

答案 1 :(得分:0)

Scala中的“类型类”意味着与“采用类型参数的类”不同的东西。这是一个特定的模式,你不应该关心,直到你对一般的类型参数感到满意,所以我会认为你的问题2是

  

是一个类,其类型参数与采用类型参数

的特征相同

答案是,类和特征之间当然存在差异(或者不会有两种不同的概念!),但这些差异是相同的,与类/特征是否具有类型参数无关。

  

特征是不同的,因为我们没有在特征中实现函数,而是让其他类这样做。

不,您可以在特征中实现方法。这是一个例子:

trait Trait[T] {
  def whatever(t: T) = Some(t)
}
  

当扩展接受Type参数的Trait时,通常通过指定实参数类型来扩展它。

再次,不:

trait Trait2[T] extends Trait[T] { ... }

在任何方面都没有问题。

class SomeClassForInt extends SomeClass[Int] { ... }