【问题标题】:Uses of the type class and difference between type class and type trait类型类的使用以及类型类和类型特征之间的区别
【发布时间】:2017-03-15 17:57:44
【问题描述】:

两个问题

问题 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

Traits 是不同的,因为我们没有在 trait 中实现函数,而是让其他类来实现。扩展一个接受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 type class 和 type trait 一样吗?

【问题讨论】:

    标签: scala class types


    【解决方案1】:

    带类型参数的类有什么用

    当您可以对类型参数进行抽象时,多态类很有用。这意味着您的类所公开的操作并非特定于某些具体类型。

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

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

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

    你不想那样做,因为没有理由。由于我们可以抽象任何类型参数A,因此可以将类或特征设为泛型,以便map 等操作可以采用这些抽象类型的高阶函数。

    类型类与类型特征相同吗?

    不确定您所说的“相同”是什么意思。阶级和性状本质上是不同的,具有不同的品质。

    【讨论】:

    • 谢谢。我也开始形成相同的观点,即 Type 类应该用于通用的东西,而不是特定于类的东西。我是否正确地说,在实现类型类时,我将仅限于使用所有类都可用的那些构造?
    • @ManuChadha 大多数情况下是的,但不一定总是。类型类可以具有约束,例如lower bounds and upper bounds.,它使您能够查看类型参数T 的属性,这些属性在所有T 之间共享。
    【解决方案2】:

    Scala 中的“类型类”的含义与“接受类型参数的类”不同。这是一种特定模式,除非您对一般类型参数感到满意,否则您不应该关心它,所以我认为您的问题 2 是

    是一个接受类型参数的类,与一个接受类型参数的特征相同

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

    Traits 是不同的,因为我们没有在 trait 中实现函数,而是让其他类来实现。

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

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

    接受Type参数的Trait扩展时,一般通过指定实参类型进行扩展。

    再次,不:

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

    在任何方面都没有问题。也不是

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

    【讨论】:

    • 谢谢。我还没有在 Scala 中,因此不知道你指出的事情。
    猜你喜欢
    • 2012-08-07
    • 2021-01-12
    • 2012-12-09
    • 2013-11-17
    • 2013-05-19
    • 2015-11-07
    • 2013-10-05
    • 2016-09-28
    • 1970-01-01
    相关资源
    最近更新 更多